@reverbia/sdk 1.0.0-next.20251219154503 → 1.0.0-next.20251219162520

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.
@@ -337,7 +337,7 @@ var import_react2 = require("react");
337
337
  var import_watermelondb = require("@nozbe/watermelondb");
338
338
  var import_migrations = require("@nozbe/watermelondb/Schema/migrations");
339
339
  var chatStorageSchema = (0, import_watermelondb.appSchema)({
340
- version: 2,
340
+ version: 3,
341
341
  tables: [
342
342
  (0, import_watermelondb.tableSchema)({
343
343
  name: "history",
@@ -355,7 +355,8 @@ var chatStorageSchema = (0, import_watermelondb.appSchema)({
355
355
  { name: "usage", type: "string", isOptional: true },
356
356
  { name: "sources", type: "string", isOptional: true },
357
357
  { name: "response_duration", type: "number", isOptional: true },
358
- { name: "was_stopped", type: "boolean", isOptional: true }
358
+ { name: "was_stopped", type: "boolean", isOptional: true },
359
+ { name: "error", type: "string", isOptional: true }
359
360
  ]
360
361
  }),
361
362
  (0, import_watermelondb.tableSchema)({
@@ -380,6 +381,15 @@ var chatStorageMigrations = (0, import_migrations.schemaMigrations)({
380
381
  columns: [{ name: "was_stopped", type: "boolean", isOptional: true }]
381
382
  })
382
383
  ]
384
+ },
385
+ {
386
+ toVersion: 3,
387
+ steps: [
388
+ (0, import_migrations.addColumns)({
389
+ table: "history",
390
+ columns: [{ name: "error", type: "string", isOptional: true }]
391
+ })
392
+ ]
383
393
  }
384
394
  ]
385
395
  });
@@ -435,6 +445,9 @@ __decorateClass([
435
445
  __decorateClass([
436
446
  (0, import_decorators.field)("was_stopped")
437
447
  ], Message.prototype, "wasStopped", 2);
448
+ __decorateClass([
449
+ (0, import_decorators.text)("error")
450
+ ], Message.prototype, "error", 2);
438
451
  var Conversation = class extends import_watermelondb2.Model {
439
452
  };
440
453
  Conversation.table = "conversations";
@@ -489,7 +502,8 @@ function messageToStored(message) {
489
502
  usage: message.usage,
490
503
  sources: message.sources,
491
504
  responseDuration: message.responseDuration,
492
- wasStopped: message.wasStopped
505
+ wasStopped: message.wasStopped,
506
+ error: message.error
493
507
  };
494
508
  }
495
509
  function conversationToStored(conversation) {
@@ -579,10 +593,25 @@ async function createMessageOp(ctx, opts) {
579
593
  if (opts.vector) msg._setRaw("vector", JSON.stringify(opts.vector));
580
594
  if (opts.embeddingModel) msg._setRaw("embedding_model", opts.embeddingModel);
581
595
  if (opts.wasStopped) msg._setRaw("was_stopped", opts.wasStopped);
596
+ if (opts.error) msg._setRaw("error", opts.error);
582
597
  });
583
598
  });
584
599
  return messageToStored(created);
585
600
  }
601
+ async function updateMessageErrorOp(ctx, uniqueId, error) {
602
+ let message;
603
+ try {
604
+ message = await ctx.messagesCollection.find(uniqueId);
605
+ } catch {
606
+ return null;
607
+ }
608
+ await ctx.database.write(async () => {
609
+ await message.update((msg) => {
610
+ msg._setRaw("error", error);
611
+ });
612
+ });
613
+ return messageToStored(message);
614
+ }
586
615
 
587
616
  // src/expo/useChatStorage.ts
588
617
  function storedToLlmapiMessage(stored) {
@@ -748,7 +777,8 @@ function useChatStorage(options) {
748
777
  let messagesToSend = [];
749
778
  if (includeHistory && !providedMessages) {
750
779
  const storedMessages = await getMessages(convId);
751
- const limitedMessages = storedMessages.slice(-maxHistoryMessages);
780
+ const validMessages = storedMessages.filter((msg) => !msg.error);
781
+ const limitedMessages = validMessages.slice(-maxHistoryMessages);
752
782
  messagesToSend = limitedMessages.map(storedToLlmapiMessage);
753
783
  } else if (providedMessages) {
754
784
  messagesToSend = providedMessages;
@@ -838,12 +868,34 @@ function useChatStorage(options) {
838
868
  assistantMessage: storedAssistantMessage2
839
869
  };
840
870
  } catch {
871
+ return {
872
+ data: null,
873
+ error: "Request aborted",
874
+ userMessage: storedUserMessage
875
+ };
841
876
  }
842
877
  }
878
+ const errorMessage = result.error || "No response data received";
879
+ try {
880
+ await updateMessageErrorOp(
881
+ storageCtx,
882
+ storedUserMessage.uniqueId,
883
+ errorMessage
884
+ );
885
+ await createMessageOp(storageCtx, {
886
+ conversationId: convId,
887
+ role: "assistant",
888
+ content: "",
889
+ model: model || "",
890
+ responseDuration,
891
+ error: errorMessage
892
+ });
893
+ } catch {
894
+ }
843
895
  return {
844
896
  data: null,
845
- error: result.error || "No response data received",
846
- userMessage: storedUserMessage
897
+ error: errorMessage,
898
+ userMessage: { ...storedUserMessage, error: errorMessage }
847
899
  };
848
900
  }
849
901
  const responseData = result.data;
@@ -2959,7 +3011,7 @@ __decorateClass([
2959
3011
  ], ModelPreference.prototype, "models", 2);
2960
3012
 
2961
3013
  // src/lib/db/schema.ts
2962
- var SDK_SCHEMA_VERSION = 4;
3014
+ var SDK_SCHEMA_VERSION = 5;
2963
3015
  var sdkSchema = (0, import_watermelondb8.appSchema)({
2964
3016
  version: SDK_SCHEMA_VERSION,
2965
3017
  tables: [
@@ -2980,7 +3032,8 @@ var sdkSchema = (0, import_watermelondb8.appSchema)({
2980
3032
  { name: "usage", type: "string", isOptional: true },
2981
3033
  { name: "sources", type: "string", isOptional: true },
2982
3034
  { name: "response_duration", type: "number", isOptional: true },
2983
- { name: "was_stopped", type: "boolean", isOptional: true }
3035
+ { name: "was_stopped", type: "boolean", isOptional: true },
3036
+ { name: "error", type: "string", isOptional: true }
2984
3037
  ]
2985
3038
  }),
2986
3039
  (0, import_watermelondb8.tableSchema)({
@@ -3047,6 +3100,16 @@ var sdkMigrations = (0, import_migrations2.schemaMigrations)({
3047
3100
  ]
3048
3101
  })
3049
3102
  ]
3103
+ },
3104
+ // v4 -> v5: Added error column to history for error persistence
3105
+ {
3106
+ toVersion: 5,
3107
+ steps: [
3108
+ (0, import_migrations2.addColumns)({
3109
+ table: "history",
3110
+ columns: [{ name: "error", type: "string", isOptional: true }]
3111
+ })
3112
+ ]
3050
3113
  }
3051
3114
  ]
3052
3115
  });
@@ -457,6 +457,8 @@ interface StoredMessage {
457
457
  sources?: SearchSource[];
458
458
  responseDuration?: number;
459
459
  wasStopped?: boolean;
460
+ /** If set, indicates the message failed with this error */
461
+ error?: string;
460
462
  }
461
463
  interface StoredConversation {
462
464
  uniqueId: string;
@@ -481,6 +483,8 @@ interface CreateMessageOptions {
481
483
  vector?: number[];
482
484
  embeddingModel?: string;
483
485
  wasStopped?: boolean;
486
+ /** If set, indicates the message failed with this error */
487
+ error?: string;
484
488
  }
485
489
  interface CreateConversationOptions {
486
490
  conversationId?: string;
@@ -555,6 +559,7 @@ declare class Message extends Model {
555
559
  sources?: SearchSource[];
556
560
  responseDuration?: number;
557
561
  wasStopped?: boolean;
562
+ error?: string;
558
563
  }
559
564
  declare class Conversation extends Model {
560
565
  static table: string;
@@ -918,6 +923,7 @@ declare const sdkSchema: Readonly<{
918
923
  * Migration history:
919
924
  * - v2 → v3: Added `was_stopped` column to history table
920
925
  * - v3 → v4: Added `modelPreferences` table for settings storage
926
+ * - v4 → v5: Added `error` column to history table for error persistence
921
927
  */
922
928
  declare const sdkMigrations: Readonly<{
923
929
  validated: true;
@@ -457,6 +457,8 @@ interface StoredMessage {
457
457
  sources?: SearchSource[];
458
458
  responseDuration?: number;
459
459
  wasStopped?: boolean;
460
+ /** If set, indicates the message failed with this error */
461
+ error?: string;
460
462
  }
461
463
  interface StoredConversation {
462
464
  uniqueId: string;
@@ -481,6 +483,8 @@ interface CreateMessageOptions {
481
483
  vector?: number[];
482
484
  embeddingModel?: string;
483
485
  wasStopped?: boolean;
486
+ /** If set, indicates the message failed with this error */
487
+ error?: string;
484
488
  }
485
489
  interface CreateConversationOptions {
486
490
  conversationId?: string;
@@ -555,6 +559,7 @@ declare class Message extends Model {
555
559
  sources?: SearchSource[];
556
560
  responseDuration?: number;
557
561
  wasStopped?: boolean;
562
+ error?: string;
558
563
  }
559
564
  declare class Conversation extends Model {
560
565
  static table: string;
@@ -918,6 +923,7 @@ declare const sdkSchema: Readonly<{
918
923
  * Migration history:
919
924
  * - v2 → v3: Added `was_stopped` column to history table
920
925
  * - v3 → v4: Added `modelPreferences` table for settings storage
926
+ * - v4 → v5: Added `error` column to history table for error persistence
921
927
  */
922
928
  declare const sdkMigrations: Readonly<{
923
929
  validated: true;
@@ -301,7 +301,7 @@ import {
301
301
  addColumns
302
302
  } from "@nozbe/watermelondb/Schema/migrations";
303
303
  var chatStorageSchema = appSchema({
304
- version: 2,
304
+ version: 3,
305
305
  tables: [
306
306
  tableSchema({
307
307
  name: "history",
@@ -319,7 +319,8 @@ var chatStorageSchema = appSchema({
319
319
  { name: "usage", type: "string", isOptional: true },
320
320
  { name: "sources", type: "string", isOptional: true },
321
321
  { name: "response_duration", type: "number", isOptional: true },
322
- { name: "was_stopped", type: "boolean", isOptional: true }
322
+ { name: "was_stopped", type: "boolean", isOptional: true },
323
+ { name: "error", type: "string", isOptional: true }
323
324
  ]
324
325
  }),
325
326
  tableSchema({
@@ -344,6 +345,15 @@ var chatStorageMigrations = schemaMigrations({
344
345
  columns: [{ name: "was_stopped", type: "boolean", isOptional: true }]
345
346
  })
346
347
  ]
348
+ },
349
+ {
350
+ toVersion: 3,
351
+ steps: [
352
+ addColumns({
353
+ table: "history",
354
+ columns: [{ name: "error", type: "string", isOptional: true }]
355
+ })
356
+ ]
347
357
  }
348
358
  ]
349
359
  });
@@ -399,6 +409,9 @@ __decorateClass([
399
409
  __decorateClass([
400
410
  field("was_stopped")
401
411
  ], Message.prototype, "wasStopped", 2);
412
+ __decorateClass([
413
+ text("error")
414
+ ], Message.prototype, "error", 2);
402
415
  var Conversation = class extends Model {
403
416
  };
404
417
  Conversation.table = "conversations";
@@ -453,7 +466,8 @@ function messageToStored(message) {
453
466
  usage: message.usage,
454
467
  sources: message.sources,
455
468
  responseDuration: message.responseDuration,
456
- wasStopped: message.wasStopped
469
+ wasStopped: message.wasStopped,
470
+ error: message.error
457
471
  };
458
472
  }
459
473
  function conversationToStored(conversation) {
@@ -543,10 +557,25 @@ async function createMessageOp(ctx, opts) {
543
557
  if (opts.vector) msg._setRaw("vector", JSON.stringify(opts.vector));
544
558
  if (opts.embeddingModel) msg._setRaw("embedding_model", opts.embeddingModel);
545
559
  if (opts.wasStopped) msg._setRaw("was_stopped", opts.wasStopped);
560
+ if (opts.error) msg._setRaw("error", opts.error);
546
561
  });
547
562
  });
548
563
  return messageToStored(created);
549
564
  }
565
+ async function updateMessageErrorOp(ctx, uniqueId, error) {
566
+ let message;
567
+ try {
568
+ message = await ctx.messagesCollection.find(uniqueId);
569
+ } catch {
570
+ return null;
571
+ }
572
+ await ctx.database.write(async () => {
573
+ await message.update((msg) => {
574
+ msg._setRaw("error", error);
575
+ });
576
+ });
577
+ return messageToStored(message);
578
+ }
550
579
 
551
580
  // src/expo/useChatStorage.ts
552
581
  function storedToLlmapiMessage(stored) {
@@ -712,7 +741,8 @@ function useChatStorage(options) {
712
741
  let messagesToSend = [];
713
742
  if (includeHistory && !providedMessages) {
714
743
  const storedMessages = await getMessages(convId);
715
- const limitedMessages = storedMessages.slice(-maxHistoryMessages);
744
+ const validMessages = storedMessages.filter((msg) => !msg.error);
745
+ const limitedMessages = validMessages.slice(-maxHistoryMessages);
716
746
  messagesToSend = limitedMessages.map(storedToLlmapiMessage);
717
747
  } else if (providedMessages) {
718
748
  messagesToSend = providedMessages;
@@ -802,12 +832,34 @@ function useChatStorage(options) {
802
832
  assistantMessage: storedAssistantMessage2
803
833
  };
804
834
  } catch {
835
+ return {
836
+ data: null,
837
+ error: "Request aborted",
838
+ userMessage: storedUserMessage
839
+ };
805
840
  }
806
841
  }
842
+ const errorMessage = result.error || "No response data received";
843
+ try {
844
+ await updateMessageErrorOp(
845
+ storageCtx,
846
+ storedUserMessage.uniqueId,
847
+ errorMessage
848
+ );
849
+ await createMessageOp(storageCtx, {
850
+ conversationId: convId,
851
+ role: "assistant",
852
+ content: "",
853
+ model: model || "",
854
+ responseDuration,
855
+ error: errorMessage
856
+ });
857
+ } catch {
858
+ }
807
859
  return {
808
860
  data: null,
809
- error: result.error || "No response data received",
810
- userMessage: storedUserMessage
861
+ error: errorMessage,
862
+ userMessage: { ...storedUserMessage, error: errorMessage }
811
863
  };
812
864
  }
813
865
  const responseData = result.data;
@@ -2927,7 +2979,7 @@ __decorateClass([
2927
2979
  ], ModelPreference.prototype, "models", 2);
2928
2980
 
2929
2981
  // src/lib/db/schema.ts
2930
- var SDK_SCHEMA_VERSION = 4;
2982
+ var SDK_SCHEMA_VERSION = 5;
2931
2983
  var sdkSchema = appSchema3({
2932
2984
  version: SDK_SCHEMA_VERSION,
2933
2985
  tables: [
@@ -2948,7 +3000,8 @@ var sdkSchema = appSchema3({
2948
3000
  { name: "usage", type: "string", isOptional: true },
2949
3001
  { name: "sources", type: "string", isOptional: true },
2950
3002
  { name: "response_duration", type: "number", isOptional: true },
2951
- { name: "was_stopped", type: "boolean", isOptional: true }
3003
+ { name: "was_stopped", type: "boolean", isOptional: true },
3004
+ { name: "error", type: "string", isOptional: true }
2952
3005
  ]
2953
3006
  }),
2954
3007
  tableSchema3({
@@ -3015,6 +3068,16 @@ var sdkMigrations = schemaMigrations2({
3015
3068
  ]
3016
3069
  })
3017
3070
  ]
3071
+ },
3072
+ // v4 -> v5: Added error column to history for error persistence
3073
+ {
3074
+ toVersion: 5,
3075
+ steps: [
3076
+ addColumns2({
3077
+ table: "history",
3078
+ columns: [{ name: "error", type: "string", isOptional: true }]
3079
+ })
3080
+ ]
3018
3081
  }
3019
3082
  ]
3020
3083
  });
@@ -1795,7 +1795,7 @@ var import_react2 = require("react");
1795
1795
  var import_watermelondb = require("@nozbe/watermelondb");
1796
1796
  var import_migrations = require("@nozbe/watermelondb/Schema/migrations");
1797
1797
  var chatStorageSchema = (0, import_watermelondb.appSchema)({
1798
- version: 2,
1798
+ version: 3,
1799
1799
  tables: [
1800
1800
  (0, import_watermelondb.tableSchema)({
1801
1801
  name: "history",
@@ -1813,7 +1813,8 @@ var chatStorageSchema = (0, import_watermelondb.appSchema)({
1813
1813
  { name: "usage", type: "string", isOptional: true },
1814
1814
  { name: "sources", type: "string", isOptional: true },
1815
1815
  { name: "response_duration", type: "number", isOptional: true },
1816
- { name: "was_stopped", type: "boolean", isOptional: true }
1816
+ { name: "was_stopped", type: "boolean", isOptional: true },
1817
+ { name: "error", type: "string", isOptional: true }
1817
1818
  ]
1818
1819
  }),
1819
1820
  (0, import_watermelondb.tableSchema)({
@@ -1838,6 +1839,15 @@ var chatStorageMigrations = (0, import_migrations.schemaMigrations)({
1838
1839
  columns: [{ name: "was_stopped", type: "boolean", isOptional: true }]
1839
1840
  })
1840
1841
  ]
1842
+ },
1843
+ {
1844
+ toVersion: 3,
1845
+ steps: [
1846
+ (0, import_migrations.addColumns)({
1847
+ table: "history",
1848
+ columns: [{ name: "error", type: "string", isOptional: true }]
1849
+ })
1850
+ ]
1841
1851
  }
1842
1852
  ]
1843
1853
  });
@@ -1893,6 +1903,9 @@ __decorateClass([
1893
1903
  __decorateClass([
1894
1904
  (0, import_decorators.field)("was_stopped")
1895
1905
  ], Message.prototype, "wasStopped", 2);
1906
+ __decorateClass([
1907
+ (0, import_decorators.text)("error")
1908
+ ], Message.prototype, "error", 2);
1896
1909
  var Conversation = class extends import_watermelondb2.Model {
1897
1910
  };
1898
1911
  Conversation.table = "conversations";
@@ -1947,7 +1960,8 @@ function messageToStored(message) {
1947
1960
  usage: message.usage,
1948
1961
  sources: message.sources,
1949
1962
  responseDuration: message.responseDuration,
1950
- wasStopped: message.wasStopped
1963
+ wasStopped: message.wasStopped,
1964
+ error: message.error
1951
1965
  };
1952
1966
  }
1953
1967
  function conversationToStored(conversation) {
@@ -2037,6 +2051,7 @@ async function createMessageOp(ctx, opts) {
2037
2051
  if (opts.vector) msg._setRaw("vector", JSON.stringify(opts.vector));
2038
2052
  if (opts.embeddingModel) msg._setRaw("embedding_model", opts.embeddingModel);
2039
2053
  if (opts.wasStopped) msg._setRaw("was_stopped", opts.wasStopped);
2054
+ if (opts.error) msg._setRaw("error", opts.error);
2040
2055
  });
2041
2056
  });
2042
2057
  return messageToStored(created);
@@ -2056,6 +2071,20 @@ async function updateMessageEmbeddingOp(ctx, uniqueId, vector, embeddingModel) {
2056
2071
  });
2057
2072
  return messageToStored(message);
2058
2073
  }
2074
+ async function updateMessageErrorOp(ctx, uniqueId, error) {
2075
+ let message;
2076
+ try {
2077
+ message = await ctx.messagesCollection.find(uniqueId);
2078
+ } catch {
2079
+ return null;
2080
+ }
2081
+ await ctx.database.write(async () => {
2082
+ await message.update((msg) => {
2083
+ msg._setRaw("error", error);
2084
+ });
2085
+ });
2086
+ return messageToStored(message);
2087
+ }
2059
2088
  function cosineSimilarity(a, b) {
2060
2089
  if (a.length !== b.length) return 0;
2061
2090
  let dotProduct = 0;
@@ -2273,7 +2302,8 @@ function useChatStorage(options) {
2273
2302
  let messagesToSend = [];
2274
2303
  if (includeHistory && !providedMessages) {
2275
2304
  const storedMessages = await getMessages(convId);
2276
- const limitedMessages = storedMessages.slice(-maxHistoryMessages);
2305
+ const validMessages = storedMessages.filter((msg) => !msg.error);
2306
+ const limitedMessages = validMessages.slice(-maxHistoryMessages);
2277
2307
  messagesToSend = limitedMessages.map(storedToLlmapiMessage);
2278
2308
  } else if (providedMessages) {
2279
2309
  messagesToSend = providedMessages;
@@ -2372,14 +2402,37 @@ function useChatStorage(options) {
2372
2402
  userMessage: storedUserMessage,
2373
2403
  assistantMessage: storedAssistantMessage2
2374
2404
  };
2375
- } catch (err) {
2405
+ } catch {
2406
+ return {
2407
+ data: null,
2408
+ error: "Request aborted",
2409
+ toolExecution: abortedResult.toolExecution,
2410
+ userMessage: storedUserMessage
2411
+ };
2376
2412
  }
2377
2413
  }
2414
+ const errorMessage = result.error || "No response data received";
2415
+ try {
2416
+ await updateMessageErrorOp(
2417
+ storageCtx,
2418
+ storedUserMessage.uniqueId,
2419
+ errorMessage
2420
+ );
2421
+ await createMessageOp(storageCtx, {
2422
+ conversationId: convId,
2423
+ role: "assistant",
2424
+ content: "",
2425
+ model: model || "",
2426
+ responseDuration,
2427
+ error: errorMessage
2428
+ });
2429
+ } catch {
2430
+ }
2378
2431
  return {
2379
2432
  data: null,
2380
- error: result.error || "No response data received",
2433
+ error: errorMessage,
2381
2434
  toolExecution: result.toolExecution,
2382
- userMessage: storedUserMessage
2435
+ userMessage: { ...storedUserMessage, error: errorMessage }
2383
2436
  };
2384
2437
  }
2385
2438
  const responseData = result.data;
@@ -2517,7 +2570,7 @@ __decorateClass([
2517
2570
  ], ModelPreference.prototype, "models", 2);
2518
2571
 
2519
2572
  // src/lib/db/schema.ts
2520
- var SDK_SCHEMA_VERSION = 4;
2573
+ var SDK_SCHEMA_VERSION = 5;
2521
2574
  var sdkSchema = (0, import_watermelondb6.appSchema)({
2522
2575
  version: SDK_SCHEMA_VERSION,
2523
2576
  tables: [
@@ -2538,7 +2591,8 @@ var sdkSchema = (0, import_watermelondb6.appSchema)({
2538
2591
  { name: "usage", type: "string", isOptional: true },
2539
2592
  { name: "sources", type: "string", isOptional: true },
2540
2593
  { name: "response_duration", type: "number", isOptional: true },
2541
- { name: "was_stopped", type: "boolean", isOptional: true }
2594
+ { name: "was_stopped", type: "boolean", isOptional: true },
2595
+ { name: "error", type: "string", isOptional: true }
2542
2596
  ]
2543
2597
  }),
2544
2598
  (0, import_watermelondb6.tableSchema)({
@@ -2605,6 +2659,16 @@ var sdkMigrations = (0, import_migrations2.schemaMigrations)({
2605
2659
  ]
2606
2660
  })
2607
2661
  ]
2662
+ },
2663
+ // v4 -> v5: Added error column to history for error persistence
2664
+ {
2665
+ toVersion: 5,
2666
+ steps: [
2667
+ (0, import_migrations2.addColumns)({
2668
+ table: "history",
2669
+ columns: [{ name: "error", type: "string", isOptional: true }]
2670
+ })
2671
+ ]
2608
2672
  }
2609
2673
  ]
2610
2674
  });
@@ -978,6 +978,8 @@ interface StoredMessage {
978
978
  sources?: SearchSource[];
979
979
  responseDuration?: number;
980
980
  wasStopped?: boolean;
981
+ /** If set, indicates the message failed with this error */
982
+ error?: string;
981
983
  }
982
984
  interface StoredConversation {
983
985
  uniqueId: string;
@@ -1002,6 +1004,8 @@ interface CreateMessageOptions {
1002
1004
  vector?: number[];
1003
1005
  embeddingModel?: string;
1004
1006
  wasStopped?: boolean;
1007
+ /** If set, indicates the message failed with this error */
1008
+ error?: string;
1005
1009
  }
1006
1010
  interface CreateConversationOptions {
1007
1011
  conversationId?: string;
@@ -1063,6 +1067,7 @@ declare class Message extends Model {
1063
1067
  sources?: SearchSource[];
1064
1068
  responseDuration?: number;
1065
1069
  wasStopped?: boolean;
1070
+ error?: string;
1066
1071
  }
1067
1072
  declare class Conversation extends Model {
1068
1073
  static table: string;
@@ -1248,6 +1253,7 @@ declare const sdkSchema: Readonly<{
1248
1253
  * Migration history:
1249
1254
  * - v2 → v3: Added `was_stopped` column to history table
1250
1255
  * - v3 → v4: Added `modelPreferences` table for settings storage
1256
+ * - v4 → v5: Added `error` column to history table for error persistence
1251
1257
  */
1252
1258
  declare const sdkMigrations: Readonly<{
1253
1259
  validated: true;
@@ -978,6 +978,8 @@ interface StoredMessage {
978
978
  sources?: SearchSource[];
979
979
  responseDuration?: number;
980
980
  wasStopped?: boolean;
981
+ /** If set, indicates the message failed with this error */
982
+ error?: string;
981
983
  }
982
984
  interface StoredConversation {
983
985
  uniqueId: string;
@@ -1002,6 +1004,8 @@ interface CreateMessageOptions {
1002
1004
  vector?: number[];
1003
1005
  embeddingModel?: string;
1004
1006
  wasStopped?: boolean;
1007
+ /** If set, indicates the message failed with this error */
1008
+ error?: string;
1005
1009
  }
1006
1010
  interface CreateConversationOptions {
1007
1011
  conversationId?: string;
@@ -1063,6 +1067,7 @@ declare class Message extends Model {
1063
1067
  sources?: SearchSource[];
1064
1068
  responseDuration?: number;
1065
1069
  wasStopped?: boolean;
1070
+ error?: string;
1066
1071
  }
1067
1072
  declare class Conversation extends Model {
1068
1073
  static table: string;
@@ -1248,6 +1253,7 @@ declare const sdkSchema: Readonly<{
1248
1253
  * Migration history:
1249
1254
  * - v2 → v3: Added `was_stopped` column to history table
1250
1255
  * - v3 → v4: Added `modelPreferences` table for settings storage
1256
+ * - v4 → v5: Added `error` column to history table for error persistence
1251
1257
  */
1252
1258
  declare const sdkMigrations: Readonly<{
1253
1259
  validated: true;
@@ -1704,7 +1704,7 @@ import {
1704
1704
  addColumns
1705
1705
  } from "@nozbe/watermelondb/Schema/migrations";
1706
1706
  var chatStorageSchema = appSchema({
1707
- version: 2,
1707
+ version: 3,
1708
1708
  tables: [
1709
1709
  tableSchema({
1710
1710
  name: "history",
@@ -1722,7 +1722,8 @@ var chatStorageSchema = appSchema({
1722
1722
  { name: "usage", type: "string", isOptional: true },
1723
1723
  { name: "sources", type: "string", isOptional: true },
1724
1724
  { name: "response_duration", type: "number", isOptional: true },
1725
- { name: "was_stopped", type: "boolean", isOptional: true }
1725
+ { name: "was_stopped", type: "boolean", isOptional: true },
1726
+ { name: "error", type: "string", isOptional: true }
1726
1727
  ]
1727
1728
  }),
1728
1729
  tableSchema({
@@ -1747,6 +1748,15 @@ var chatStorageMigrations = schemaMigrations({
1747
1748
  columns: [{ name: "was_stopped", type: "boolean", isOptional: true }]
1748
1749
  })
1749
1750
  ]
1751
+ },
1752
+ {
1753
+ toVersion: 3,
1754
+ steps: [
1755
+ addColumns({
1756
+ table: "history",
1757
+ columns: [{ name: "error", type: "string", isOptional: true }]
1758
+ })
1759
+ ]
1750
1760
  }
1751
1761
  ]
1752
1762
  });
@@ -1802,6 +1812,9 @@ __decorateClass([
1802
1812
  __decorateClass([
1803
1813
  field("was_stopped")
1804
1814
  ], Message.prototype, "wasStopped", 2);
1815
+ __decorateClass([
1816
+ text("error")
1817
+ ], Message.prototype, "error", 2);
1805
1818
  var Conversation = class extends Model {
1806
1819
  };
1807
1820
  Conversation.table = "conversations";
@@ -1856,7 +1869,8 @@ function messageToStored(message) {
1856
1869
  usage: message.usage,
1857
1870
  sources: message.sources,
1858
1871
  responseDuration: message.responseDuration,
1859
- wasStopped: message.wasStopped
1872
+ wasStopped: message.wasStopped,
1873
+ error: message.error
1860
1874
  };
1861
1875
  }
1862
1876
  function conversationToStored(conversation) {
@@ -1946,6 +1960,7 @@ async function createMessageOp(ctx, opts) {
1946
1960
  if (opts.vector) msg._setRaw("vector", JSON.stringify(opts.vector));
1947
1961
  if (opts.embeddingModel) msg._setRaw("embedding_model", opts.embeddingModel);
1948
1962
  if (opts.wasStopped) msg._setRaw("was_stopped", opts.wasStopped);
1963
+ if (opts.error) msg._setRaw("error", opts.error);
1949
1964
  });
1950
1965
  });
1951
1966
  return messageToStored(created);
@@ -1965,6 +1980,20 @@ async function updateMessageEmbeddingOp(ctx, uniqueId, vector, embeddingModel) {
1965
1980
  });
1966
1981
  return messageToStored(message);
1967
1982
  }
1983
+ async function updateMessageErrorOp(ctx, uniqueId, error) {
1984
+ let message;
1985
+ try {
1986
+ message = await ctx.messagesCollection.find(uniqueId);
1987
+ } catch {
1988
+ return null;
1989
+ }
1990
+ await ctx.database.write(async () => {
1991
+ await message.update((msg) => {
1992
+ msg._setRaw("error", error);
1993
+ });
1994
+ });
1995
+ return messageToStored(message);
1996
+ }
1968
1997
  function cosineSimilarity(a, b) {
1969
1998
  if (a.length !== b.length) return 0;
1970
1999
  let dotProduct = 0;
@@ -2182,7 +2211,8 @@ function useChatStorage(options) {
2182
2211
  let messagesToSend = [];
2183
2212
  if (includeHistory && !providedMessages) {
2184
2213
  const storedMessages = await getMessages(convId);
2185
- const limitedMessages = storedMessages.slice(-maxHistoryMessages);
2214
+ const validMessages = storedMessages.filter((msg) => !msg.error);
2215
+ const limitedMessages = validMessages.slice(-maxHistoryMessages);
2186
2216
  messagesToSend = limitedMessages.map(storedToLlmapiMessage);
2187
2217
  } else if (providedMessages) {
2188
2218
  messagesToSend = providedMessages;
@@ -2281,14 +2311,37 @@ function useChatStorage(options) {
2281
2311
  userMessage: storedUserMessage,
2282
2312
  assistantMessage: storedAssistantMessage2
2283
2313
  };
2284
- } catch (err) {
2314
+ } catch {
2315
+ return {
2316
+ data: null,
2317
+ error: "Request aborted",
2318
+ toolExecution: abortedResult.toolExecution,
2319
+ userMessage: storedUserMessage
2320
+ };
2285
2321
  }
2286
2322
  }
2323
+ const errorMessage = result.error || "No response data received";
2324
+ try {
2325
+ await updateMessageErrorOp(
2326
+ storageCtx,
2327
+ storedUserMessage.uniqueId,
2328
+ errorMessage
2329
+ );
2330
+ await createMessageOp(storageCtx, {
2331
+ conversationId: convId,
2332
+ role: "assistant",
2333
+ content: "",
2334
+ model: model || "",
2335
+ responseDuration,
2336
+ error: errorMessage
2337
+ });
2338
+ } catch {
2339
+ }
2287
2340
  return {
2288
2341
  data: null,
2289
- error: result.error || "No response data received",
2342
+ error: errorMessage,
2290
2343
  toolExecution: result.toolExecution,
2291
- userMessage: storedUserMessage
2344
+ userMessage: { ...storedUserMessage, error: errorMessage }
2292
2345
  };
2293
2346
  }
2294
2347
  const responseData = result.data;
@@ -2430,7 +2483,7 @@ __decorateClass([
2430
2483
  ], ModelPreference.prototype, "models", 2);
2431
2484
 
2432
2485
  // src/lib/db/schema.ts
2433
- var SDK_SCHEMA_VERSION = 4;
2486
+ var SDK_SCHEMA_VERSION = 5;
2434
2487
  var sdkSchema = appSchema2({
2435
2488
  version: SDK_SCHEMA_VERSION,
2436
2489
  tables: [
@@ -2451,7 +2504,8 @@ var sdkSchema = appSchema2({
2451
2504
  { name: "usage", type: "string", isOptional: true },
2452
2505
  { name: "sources", type: "string", isOptional: true },
2453
2506
  { name: "response_duration", type: "number", isOptional: true },
2454
- { name: "was_stopped", type: "boolean", isOptional: true }
2507
+ { name: "was_stopped", type: "boolean", isOptional: true },
2508
+ { name: "error", type: "string", isOptional: true }
2455
2509
  ]
2456
2510
  }),
2457
2511
  tableSchema2({
@@ -2518,6 +2572,16 @@ var sdkMigrations = schemaMigrations2({
2518
2572
  ]
2519
2573
  })
2520
2574
  ]
2575
+ },
2576
+ // v4 -> v5: Added error column to history for error persistence
2577
+ {
2578
+ toVersion: 5,
2579
+ steps: [
2580
+ addColumns2({
2581
+ table: "history",
2582
+ columns: [{ name: "error", type: "string", isOptional: true }]
2583
+ })
2584
+ ]
2521
2585
  }
2522
2586
  ]
2523
2587
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reverbia/sdk",
3
- "version": "1.0.0-next.20251219154503",
3
+ "version": "1.0.0-next.20251219162520",
4
4
  "description": "",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",