@reverbia/sdk 1.0.0 → 1.1.0-next.20251230221037

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.
Files changed (110) hide show
  1. package/README.md +290 -45
  2. package/dist/expo/index.cjs +3428 -0
  3. package/dist/expo/index.d.mts +1217 -0
  4. package/dist/expo/index.d.ts +1217 -0
  5. package/dist/expo/index.mjs +3395 -0
  6. package/dist/index.cjs +972 -0
  7. package/dist/index.d.mts +1514 -0
  8. package/dist/index.d.ts +1514 -0
  9. package/dist/index.mjs +934 -0
  10. package/dist/next/index.cjs +64 -0
  11. package/dist/next/index.d.mts +23 -0
  12. package/dist/next/index.d.ts +23 -0
  13. package/dist/next/index.mjs +39 -0
  14. package/dist/polyfills/index.cjs +61 -0
  15. package/dist/polyfills/index.d.mts +9 -0
  16. package/dist/polyfills/index.d.ts +9 -0
  17. package/dist/polyfills/index.mjs +34 -0
  18. package/dist/react/chunk-KUFGQF6E.mjs +290 -0
  19. package/dist/react/chunk-T56Y62G7.mjs +410 -0
  20. package/dist/react/index.cjs +7982 -0
  21. package/dist/react/index.d.mts +3139 -0
  22. package/dist/react/index.d.ts +3139 -0
  23. package/dist/react/index.mjs +7209 -0
  24. package/dist/react/storage-Z2NBANCK.mjs +29 -0
  25. package/dist/react/useEncryption-5RTXKDNZ.mjs +31 -0
  26. package/dist/vercel/index.cjs +86 -0
  27. package/dist/vercel/index.d.mts +119 -0
  28. package/dist/vercel/index.d.ts +119 -0
  29. package/dist/vercel/index.mjs +57 -0
  30. package/package.json +91 -16
  31. package/dist/cjs/client/client/client.gen.d.ts +0 -2
  32. package/dist/cjs/client/client/client.gen.js +0 -203
  33. package/dist/cjs/client/client/index.d.ts +0 -8
  34. package/dist/cjs/client/client/index.js +0 -16
  35. package/dist/cjs/client/client/types.gen.d.ts +0 -99
  36. package/dist/cjs/client/client/types.gen.js +0 -3
  37. package/dist/cjs/client/client/utils.gen.d.ts +0 -40
  38. package/dist/cjs/client/client/utils.gen.js +0 -314
  39. package/dist/cjs/client/client.gen.d.ts +0 -12
  40. package/dist/cjs/client/client.gen.js +0 -6
  41. package/dist/cjs/client/core/auth.gen.d.ts +0 -18
  42. package/dist/cjs/client/core/auth.gen.js +0 -18
  43. package/dist/cjs/client/core/bodySerializer.gen.d.ts +0 -25
  44. package/dist/cjs/client/core/bodySerializer.gen.js +0 -60
  45. package/dist/cjs/client/core/params.gen.d.ts +0 -43
  46. package/dist/cjs/client/core/params.gen.js +0 -104
  47. package/dist/cjs/client/core/pathSerializer.gen.d.ts +0 -33
  48. package/dist/cjs/client/core/pathSerializer.gen.js +0 -123
  49. package/dist/cjs/client/core/queryKeySerializer.gen.d.ts +0 -18
  50. package/dist/cjs/client/core/queryKeySerializer.gen.js +0 -105
  51. package/dist/cjs/client/core/serverSentEvents.gen.d.ts +0 -71
  52. package/dist/cjs/client/core/serverSentEvents.gen.js +0 -139
  53. package/dist/cjs/client/core/types.gen.d.ts +0 -78
  54. package/dist/cjs/client/core/types.gen.js +0 -3
  55. package/dist/cjs/client/core/utils.gen.d.ts +0 -19
  56. package/dist/cjs/client/core/utils.gen.js +0 -93
  57. package/dist/cjs/client/index.d.ts +0 -2
  58. package/dist/cjs/client/index.js +0 -18
  59. package/dist/cjs/client/sdk.gen.d.ts +0 -27
  60. package/dist/cjs/client/sdk.gen.js +0 -33
  61. package/dist/cjs/client/types.gen.d.ts +0 -120
  62. package/dist/cjs/client/types.gen.js +0 -3
  63. package/dist/esm/client/client/client.gen.d.ts +0 -2
  64. package/dist/esm/client/client/client.gen.js +0 -199
  65. package/dist/esm/client/client/index.d.ts +0 -8
  66. package/dist/esm/client/client/index.js +0 -6
  67. package/dist/esm/client/client/types.gen.d.ts +0 -99
  68. package/dist/esm/client/client/types.gen.js +0 -2
  69. package/dist/esm/client/client/utils.gen.d.ts +0 -40
  70. package/dist/esm/client/client/utils.gen.js +0 -302
  71. package/dist/esm/client/client.gen.d.ts +0 -12
  72. package/dist/esm/client/client.gen.js +0 -3
  73. package/dist/esm/client/core/auth.gen.d.ts +0 -18
  74. package/dist/esm/client/core/auth.gen.js +0 -14
  75. package/dist/esm/client/core/bodySerializer.gen.d.ts +0 -25
  76. package/dist/esm/client/core/bodySerializer.gen.js +0 -57
  77. package/dist/esm/client/core/params.gen.d.ts +0 -43
  78. package/dist/esm/client/core/params.gen.js +0 -100
  79. package/dist/esm/client/core/pathSerializer.gen.d.ts +0 -33
  80. package/dist/esm/client/core/pathSerializer.gen.js +0 -114
  81. package/dist/esm/client/core/queryKeySerializer.gen.d.ts +0 -18
  82. package/dist/esm/client/core/queryKeySerializer.gen.js +0 -99
  83. package/dist/esm/client/core/serverSentEvents.gen.d.ts +0 -71
  84. package/dist/esm/client/core/serverSentEvents.gen.js +0 -135
  85. package/dist/esm/client/core/types.gen.d.ts +0 -78
  86. package/dist/esm/client/core/types.gen.js +0 -2
  87. package/dist/esm/client/core/utils.gen.d.ts +0 -19
  88. package/dist/esm/client/core/utils.gen.js +0 -87
  89. package/dist/esm/client/index.d.ts +0 -2
  90. package/dist/esm/client/index.js +0 -2
  91. package/dist/esm/client/sdk.gen.d.ts +0 -27
  92. package/dist/esm/client/sdk.gen.js +0 -28
  93. package/dist/esm/client/types.gen.d.ts +0 -120
  94. package/dist/esm/client/types.gen.js +0 -2
  95. package/dist/types/client/client/client.gen.d.ts +0 -2
  96. package/dist/types/client/client/index.d.ts +0 -8
  97. package/dist/types/client/client/types.gen.d.ts +0 -99
  98. package/dist/types/client/client/utils.gen.d.ts +0 -40
  99. package/dist/types/client/client.gen.d.ts +0 -12
  100. package/dist/types/client/core/auth.gen.d.ts +0 -18
  101. package/dist/types/client/core/bodySerializer.gen.d.ts +0 -25
  102. package/dist/types/client/core/params.gen.d.ts +0 -43
  103. package/dist/types/client/core/pathSerializer.gen.d.ts +0 -33
  104. package/dist/types/client/core/queryKeySerializer.gen.d.ts +0 -18
  105. package/dist/types/client/core/serverSentEvents.gen.d.ts +0 -71
  106. package/dist/types/client/core/types.gen.d.ts +0 -78
  107. package/dist/types/client/core/utils.gen.d.ts +0 -19
  108. package/dist/types/client/index.d.ts +0 -2
  109. package/dist/types/client/sdk.gen.d.ts +0 -27
  110. package/dist/types/client/types.gen.d.ts +0 -120
@@ -0,0 +1,3395 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __decorateClass = (decorators, target, key, kind) => {
4
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
5
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
6
+ if (decorator = decorators[i])
7
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
8
+ if (kind && result) __defProp(target, key, result);
9
+ return result;
10
+ };
11
+
12
+ // src/expo/useChat.ts
13
+ import { useCallback, useEffect, useRef, useState } from "react";
14
+
15
+ // src/clientConfig.ts
16
+ var BASE_URL = "https://ai-portal-dev.zetachain.com";
17
+ var createClientConfig = (config) => ({
18
+ ...config,
19
+ baseUrl: BASE_URL
20
+ });
21
+
22
+ // src/lib/chat/useChat/utils.ts
23
+ var VALIDATION_ERROR_MESSAGES = {
24
+ messages_required: "messages are required to call sendMessage.",
25
+ model_required: "model is required to call sendMessage.",
26
+ token_getter_required: "Token getter function is required.",
27
+ token_unavailable: "No access token available."
28
+ };
29
+ function validateMessages(messages) {
30
+ if (!messages?.length) {
31
+ return {
32
+ valid: false,
33
+ error: "messages_required",
34
+ message: VALIDATION_ERROR_MESSAGES.messages_required
35
+ };
36
+ }
37
+ return { valid: true };
38
+ }
39
+ function validateModel(model) {
40
+ if (!model) {
41
+ return {
42
+ valid: false,
43
+ error: "model_required",
44
+ message: VALIDATION_ERROR_MESSAGES.model_required
45
+ };
46
+ }
47
+ return { valid: true };
48
+ }
49
+ function validateTokenGetter(getToken) {
50
+ if (!getToken) {
51
+ return {
52
+ valid: false,
53
+ error: "token_getter_required",
54
+ message: VALIDATION_ERROR_MESSAGES.token_getter_required
55
+ };
56
+ }
57
+ return { valid: true };
58
+ }
59
+ function validateToken(token) {
60
+ if (!token) {
61
+ return {
62
+ valid: false,
63
+ error: "token_unavailable",
64
+ message: VALIDATION_ERROR_MESSAGES.token_unavailable
65
+ };
66
+ }
67
+ return { valid: true };
68
+ }
69
+ function extractTextFromContentPart(part) {
70
+ if (part.type === "text" && part.text) {
71
+ return part.text;
72
+ }
73
+ return "";
74
+ }
75
+ function messagesToInput(messages) {
76
+ return messages.map((msg) => {
77
+ const role = msg.role || "user";
78
+ const content = Array.isArray(msg.content) ? msg.content.map(extractTextFromContentPart).filter(Boolean).join("\n") : String(msg.content || "");
79
+ return `${role}: ${content}`;
80
+ }).join("\n\n");
81
+ }
82
+ function createStreamAccumulator() {
83
+ return {
84
+ content: "",
85
+ thinking: "",
86
+ responseId: "",
87
+ responseModel: "",
88
+ usage: {}
89
+ };
90
+ }
91
+ function buildResponseResponse(accumulator) {
92
+ const output = [];
93
+ if (accumulator.thinking) {
94
+ output.push({
95
+ type: "reasoning",
96
+ role: "assistant",
97
+ content: [{ type: "output_text", text: accumulator.thinking }],
98
+ status: "completed"
99
+ });
100
+ }
101
+ output.push({
102
+ type: "message",
103
+ role: "assistant",
104
+ content: [{ type: "output_text", text: accumulator.content }],
105
+ status: "completed"
106
+ });
107
+ return {
108
+ id: accumulator.responseId,
109
+ model: accumulator.responseModel,
110
+ object: "response",
111
+ output,
112
+ usage: Object.keys(accumulator.usage).length > 0 ? accumulator.usage : void 0
113
+ };
114
+ }
115
+ function createErrorResult(message, onError) {
116
+ if (onError) {
117
+ onError(new Error(message));
118
+ }
119
+ return { data: null, error: message };
120
+ }
121
+ function handleError(err, onError) {
122
+ const errorMsg = err instanceof Error ? err.message : "Failed to send message.";
123
+ const errorObj = err instanceof Error ? err : new Error(errorMsg);
124
+ if (onError) {
125
+ onError(errorObj);
126
+ }
127
+ return { data: null, error: errorMsg };
128
+ }
129
+ function parseSSEDataLine(line) {
130
+ if (!line.startsWith("data: ")) {
131
+ return null;
132
+ }
133
+ const data = line.substring(6).trim();
134
+ if (data === "[DONE]") {
135
+ return null;
136
+ }
137
+ try {
138
+ return JSON.parse(data);
139
+ } catch {
140
+ return null;
141
+ }
142
+ }
143
+
144
+ // src/expo/useChat.ts
145
+ function processSSELines(lines, accumulator, onData, globalOnData, onThinking, globalOnThinking) {
146
+ for (const line of lines) {
147
+ const chunk = parseSSEDataLine(line);
148
+ if (!chunk) continue;
149
+ if (chunk.type === "response.created" && chunk.response && typeof chunk.response === "object") {
150
+ const response = chunk.response;
151
+ if (response.id && !accumulator.responseId) {
152
+ accumulator.responseId = response.id;
153
+ }
154
+ if (response.model && !accumulator.responseModel) {
155
+ accumulator.responseModel = response.model;
156
+ }
157
+ continue;
158
+ }
159
+ if (chunk.type === "response.completed" && chunk.response && typeof chunk.response === "object") {
160
+ const response = chunk.response;
161
+ if (response.usage) {
162
+ accumulator.usage = {
163
+ ...accumulator.usage,
164
+ prompt_tokens: response.usage.input_tokens,
165
+ completion_tokens: response.usage.output_tokens,
166
+ total_tokens: (response.usage.input_tokens || 0) + (response.usage.output_tokens || 0)
167
+ };
168
+ }
169
+ continue;
170
+ }
171
+ if (chunk.id && !accumulator.responseId) {
172
+ accumulator.responseId = chunk.id;
173
+ }
174
+ if (chunk.model && !accumulator.responseModel) {
175
+ accumulator.responseModel = chunk.model;
176
+ }
177
+ if (chunk.usage) {
178
+ accumulator.usage = { ...accumulator.usage, ...chunk.usage };
179
+ }
180
+ if (chunk.type === "response.reasoning.delta" || chunk.type === "response.reasoning_summary_text.delta" || chunk.type === "response.thinking.delta") {
181
+ const delta = chunk.delta;
182
+ if (delta) {
183
+ const deltaText = typeof delta === "string" ? delta : delta.OfString || delta.OfResponseReasoningSummaryDeltaEventDelta;
184
+ if (deltaText) {
185
+ accumulator.thinking += deltaText;
186
+ if (onThinking) onThinking(deltaText);
187
+ if (globalOnThinking) globalOnThinking(deltaText);
188
+ }
189
+ }
190
+ continue;
191
+ }
192
+ if (chunk.type === "response.output_text.delta" && chunk.delta) {
193
+ const deltaText = typeof chunk.delta === "string" ? chunk.delta : chunk.delta.OfString;
194
+ if (deltaText) {
195
+ accumulator.content += deltaText;
196
+ if (onData) onData(deltaText);
197
+ if (globalOnData) globalOnData(deltaText);
198
+ }
199
+ }
200
+ }
201
+ }
202
+ function useChat(options) {
203
+ const {
204
+ getToken,
205
+ baseUrl = BASE_URL,
206
+ onData: globalOnData,
207
+ onThinking: globalOnThinking,
208
+ onFinish,
209
+ onError
210
+ } = options || {};
211
+ const [isLoading, setIsLoading] = useState(false);
212
+ const abortControllerRef = useRef(null);
213
+ const stop = useCallback(() => {
214
+ if (abortControllerRef.current) {
215
+ abortControllerRef.current.abort();
216
+ abortControllerRef.current = null;
217
+ }
218
+ }, []);
219
+ useEffect(() => {
220
+ return () => {
221
+ if (abortControllerRef.current) {
222
+ abortControllerRef.current.abort();
223
+ abortControllerRef.current = null;
224
+ }
225
+ };
226
+ }, []);
227
+ const sendMessage = useCallback(
228
+ async ({
229
+ messages,
230
+ model,
231
+ onData,
232
+ onThinking,
233
+ // Responses API options
234
+ store,
235
+ previousResponseId,
236
+ conversation,
237
+ temperature,
238
+ maxOutputTokens,
239
+ tools,
240
+ toolChoice,
241
+ reasoning,
242
+ thinking
243
+ }) => {
244
+ const messagesValidation = validateMessages(messages);
245
+ if (!messagesValidation.valid) {
246
+ return createErrorResult(messagesValidation.message, onError);
247
+ }
248
+ const modelValidation = validateModel(model);
249
+ if (!modelValidation.valid) {
250
+ return createErrorResult(modelValidation.message, onError);
251
+ }
252
+ const tokenGetterValidation = validateTokenGetter(getToken);
253
+ if (!tokenGetterValidation.valid) {
254
+ return createErrorResult(tokenGetterValidation.message, onError);
255
+ }
256
+ if (abortControllerRef.current) {
257
+ abortControllerRef.current.abort();
258
+ }
259
+ const abortController = new AbortController();
260
+ abortControllerRef.current = abortController;
261
+ setIsLoading(true);
262
+ try {
263
+ const token = await getToken();
264
+ const tokenValidation = validateToken(token);
265
+ if (!tokenValidation.valid) {
266
+ setIsLoading(false);
267
+ return createErrorResult(tokenValidation.message, onError);
268
+ }
269
+ const result = await new Promise((resolve) => {
270
+ const xhr = new XMLHttpRequest();
271
+ const url = `${baseUrl}/api/v1/responses`;
272
+ const accumulator = createStreamAccumulator();
273
+ let lastProcessedIndex = 0;
274
+ let incompleteLineBuffer = "";
275
+ const abortHandler = () => {
276
+ xhr.abort();
277
+ };
278
+ abortController.signal.addEventListener("abort", abortHandler);
279
+ xhr.open("POST", url, true);
280
+ xhr.setRequestHeader("Content-Type", "application/json");
281
+ xhr.setRequestHeader("Authorization", `Bearer ${token}`);
282
+ xhr.setRequestHeader("Accept", "text/event-stream");
283
+ xhr.onprogress = () => {
284
+ const newData = xhr.responseText.substring(lastProcessedIndex);
285
+ lastProcessedIndex = xhr.responseText.length;
286
+ const dataToProcess = incompleteLineBuffer + newData;
287
+ incompleteLineBuffer = "";
288
+ const lines = dataToProcess.split("\n");
289
+ if (!newData.endsWith("\n") && lines.length > 0) {
290
+ incompleteLineBuffer = lines.pop() || "";
291
+ }
292
+ processSSELines(lines, accumulator, onData, globalOnData, onThinking, globalOnThinking);
293
+ };
294
+ xhr.onload = () => {
295
+ abortController.signal.removeEventListener("abort", abortHandler);
296
+ if (incompleteLineBuffer) {
297
+ processSSELines(
298
+ [incompleteLineBuffer.trim()],
299
+ accumulator,
300
+ onData,
301
+ globalOnData,
302
+ onThinking,
303
+ globalOnThinking
304
+ );
305
+ incompleteLineBuffer = "";
306
+ }
307
+ if (xhr.status >= 200 && xhr.status < 300) {
308
+ const response = buildResponseResponse(accumulator);
309
+ setIsLoading(false);
310
+ if (onFinish) onFinish(response);
311
+ resolve({ data: response, error: null });
312
+ } else {
313
+ const errorMsg = `Request failed with status ${xhr.status}`;
314
+ setIsLoading(false);
315
+ if (onError) onError(new Error(errorMsg));
316
+ resolve({ data: null, error: errorMsg });
317
+ }
318
+ };
319
+ xhr.onerror = () => {
320
+ abortController.signal.removeEventListener("abort", abortHandler);
321
+ const errorMsg = "Network error";
322
+ setIsLoading(false);
323
+ if (onError) onError(new Error(errorMsg));
324
+ resolve({ data: null, error: errorMsg });
325
+ };
326
+ xhr.onabort = () => {
327
+ abortController.signal.removeEventListener("abort", abortHandler);
328
+ setIsLoading(false);
329
+ resolve({ data: null, error: "Request aborted" });
330
+ };
331
+ xhr.send(
332
+ JSON.stringify({
333
+ input: messagesToInput(messages),
334
+ model,
335
+ stream: true,
336
+ // Responses API options (only include if defined)
337
+ ...store !== void 0 && { store },
338
+ ...previousResponseId && { previous_response_id: previousResponseId },
339
+ ...conversation && { conversation },
340
+ ...temperature !== void 0 && { temperature },
341
+ ...maxOutputTokens !== void 0 && { max_output_tokens: maxOutputTokens },
342
+ ...tools && { tools },
343
+ ...toolChoice && { tool_choice: toolChoice },
344
+ ...reasoning && { reasoning },
345
+ ...thinking && { thinking }
346
+ })
347
+ );
348
+ });
349
+ return result;
350
+ } catch (err) {
351
+ setIsLoading(false);
352
+ return handleError(err, onError);
353
+ } finally {
354
+ if (abortControllerRef.current === abortController) {
355
+ abortControllerRef.current = null;
356
+ }
357
+ }
358
+ },
359
+ [getToken, baseUrl, globalOnData, globalOnThinking, onFinish, onError]
360
+ );
361
+ return {
362
+ isLoading,
363
+ sendMessage,
364
+ stop
365
+ };
366
+ }
367
+
368
+ // src/expo/useChatStorage.ts
369
+ import { useCallback as useCallback2, useState as useState2, useMemo } from "react";
370
+
371
+ // src/lib/db/chat/schema.ts
372
+ import { appSchema, tableSchema } from "@nozbe/watermelondb";
373
+ import {
374
+ schemaMigrations,
375
+ addColumns
376
+ } from "@nozbe/watermelondb/Schema/migrations";
377
+ var chatStorageSchema = appSchema({
378
+ version: 5,
379
+ tables: [
380
+ tableSchema({
381
+ name: "history",
382
+ columns: [
383
+ { name: "message_id", type: "number" },
384
+ { name: "conversation_id", type: "string", isIndexed: true },
385
+ { name: "role", type: "string", isIndexed: true },
386
+ { name: "content", type: "string" },
387
+ { name: "model", type: "string", isOptional: true },
388
+ { name: "files", type: "string", isOptional: true },
389
+ { name: "created_at", type: "number", isIndexed: true },
390
+ { name: "updated_at", type: "number" },
391
+ { name: "vector", type: "string", isOptional: true },
392
+ { name: "embedding_model", type: "string", isOptional: true },
393
+ { name: "usage", type: "string", isOptional: true },
394
+ { name: "sources", type: "string", isOptional: true },
395
+ { name: "response_duration", type: "number", isOptional: true },
396
+ { name: "was_stopped", type: "boolean", isOptional: true },
397
+ { name: "error", type: "string", isOptional: true },
398
+ { name: "thought_process", type: "string", isOptional: true },
399
+ // JSON stringified ActivityPhase[]
400
+ { name: "thinking", type: "string", isOptional: true }
401
+ // Reasoning/thinking content
402
+ ]
403
+ }),
404
+ tableSchema({
405
+ name: "conversations",
406
+ columns: [
407
+ { name: "conversation_id", type: "string", isIndexed: true },
408
+ { name: "title", type: "string" },
409
+ { name: "created_at", type: "number" },
410
+ { name: "updated_at", type: "number" },
411
+ { name: "is_deleted", type: "boolean", isIndexed: true }
412
+ ]
413
+ })
414
+ ]
415
+ });
416
+ var chatStorageMigrations = schemaMigrations({
417
+ migrations: [
418
+ {
419
+ toVersion: 2,
420
+ steps: [
421
+ addColumns({
422
+ table: "history",
423
+ columns: [{ name: "was_stopped", type: "boolean", isOptional: true }]
424
+ })
425
+ ]
426
+ },
427
+ {
428
+ toVersion: 3,
429
+ steps: [
430
+ addColumns({
431
+ table: "history",
432
+ columns: [{ name: "error", type: "string", isOptional: true }]
433
+ })
434
+ ]
435
+ },
436
+ {
437
+ toVersion: 4,
438
+ steps: [
439
+ addColumns({
440
+ table: "history",
441
+ columns: [
442
+ { name: "thought_process", type: "string", isOptional: true }
443
+ ]
444
+ })
445
+ ]
446
+ },
447
+ {
448
+ toVersion: 5,
449
+ steps: [
450
+ addColumns({
451
+ table: "history",
452
+ columns: [
453
+ { name: "thinking", type: "string", isOptional: true }
454
+ ]
455
+ })
456
+ ]
457
+ }
458
+ ]
459
+ });
460
+
461
+ // src/lib/db/chat/models.ts
462
+ import { Model } from "@nozbe/watermelondb";
463
+ import { field, text, date, json } from "@nozbe/watermelondb/decorators";
464
+ var Message = class extends Model {
465
+ };
466
+ Message.table = "history";
467
+ Message.associations = {
468
+ conversations: { type: "belongs_to", key: "conversation_id" }
469
+ };
470
+ __decorateClass([
471
+ field("message_id")
472
+ ], Message.prototype, "messageId", 2);
473
+ __decorateClass([
474
+ text("conversation_id")
475
+ ], Message.prototype, "conversationId", 2);
476
+ __decorateClass([
477
+ text("role")
478
+ ], Message.prototype, "role", 2);
479
+ __decorateClass([
480
+ text("content")
481
+ ], Message.prototype, "content", 2);
482
+ __decorateClass([
483
+ text("model")
484
+ ], Message.prototype, "model", 2);
485
+ __decorateClass([
486
+ json("files", (json3) => json3)
487
+ ], Message.prototype, "files", 2);
488
+ __decorateClass([
489
+ date("created_at")
490
+ ], Message.prototype, "createdAt", 2);
491
+ __decorateClass([
492
+ date("updated_at")
493
+ ], Message.prototype, "updatedAt", 2);
494
+ __decorateClass([
495
+ json("vector", (json3) => json3)
496
+ ], Message.prototype, "vector", 2);
497
+ __decorateClass([
498
+ text("embedding_model")
499
+ ], Message.prototype, "embeddingModel", 2);
500
+ __decorateClass([
501
+ json("usage", (json3) => json3)
502
+ ], Message.prototype, "usage", 2);
503
+ __decorateClass([
504
+ json("sources", (json3) => json3)
505
+ ], Message.prototype, "sources", 2);
506
+ __decorateClass([
507
+ field("response_duration")
508
+ ], Message.prototype, "responseDuration", 2);
509
+ __decorateClass([
510
+ field("was_stopped")
511
+ ], Message.prototype, "wasStopped", 2);
512
+ __decorateClass([
513
+ text("error")
514
+ ], Message.prototype, "error", 2);
515
+ __decorateClass([
516
+ json("thought_process", (json3) => json3)
517
+ ], Message.prototype, "thoughtProcess", 2);
518
+ __decorateClass([
519
+ text("thinking")
520
+ ], Message.prototype, "thinking", 2);
521
+ var Conversation = class extends Model {
522
+ };
523
+ Conversation.table = "conversations";
524
+ Conversation.associations = {
525
+ history: { type: "has_many", foreignKey: "conversation_id" }
526
+ };
527
+ __decorateClass([
528
+ text("conversation_id")
529
+ ], Conversation.prototype, "conversationId", 2);
530
+ __decorateClass([
531
+ text("title")
532
+ ], Conversation.prototype, "title", 2);
533
+ __decorateClass([
534
+ date("created_at")
535
+ ], Conversation.prototype, "createdAt", 2);
536
+ __decorateClass([
537
+ date("updated_at")
538
+ ], Conversation.prototype, "updatedAt", 2);
539
+ __decorateClass([
540
+ field("is_deleted")
541
+ ], Conversation.prototype, "isDeleted", 2);
542
+
543
+ // src/lib/db/chat/types.ts
544
+ function generateConversationId() {
545
+ return `conv_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
546
+ }
547
+ function convertUsageToStored(usage) {
548
+ if (!usage) return void 0;
549
+ return {
550
+ promptTokens: usage.prompt_tokens,
551
+ completionTokens: usage.completion_tokens,
552
+ totalTokens: usage.total_tokens,
553
+ costMicroUsd: usage.cost_micro_usd
554
+ };
555
+ }
556
+ function finalizeThoughtProcess(thoughtProcess) {
557
+ if (!thoughtProcess?.length) return thoughtProcess;
558
+ return thoughtProcess.map(
559
+ (phase, idx) => idx === thoughtProcess.length - 1 ? { ...phase, status: "completed" } : phase
560
+ );
561
+ }
562
+
563
+ // src/lib/db/chat/operations.ts
564
+ import { Q } from "@nozbe/watermelondb";
565
+ function messageToStored(message) {
566
+ return {
567
+ uniqueId: message.id,
568
+ messageId: message.messageId,
569
+ conversationId: message.conversationId,
570
+ role: message.role,
571
+ content: message.content,
572
+ model: message.model,
573
+ files: message.files,
574
+ createdAt: message.createdAt,
575
+ updatedAt: message.updatedAt,
576
+ vector: message.vector,
577
+ embeddingModel: message.embeddingModel,
578
+ usage: message.usage,
579
+ sources: message.sources,
580
+ responseDuration: message.responseDuration,
581
+ wasStopped: message.wasStopped,
582
+ error: message.error,
583
+ thoughtProcess: message.thoughtProcess,
584
+ thinking: message.thinking
585
+ };
586
+ }
587
+ function conversationToStored(conversation) {
588
+ return {
589
+ uniqueId: conversation.id,
590
+ conversationId: conversation.conversationId,
591
+ title: conversation.title,
592
+ createdAt: conversation.createdAt,
593
+ updatedAt: conversation.updatedAt,
594
+ isDeleted: conversation.isDeleted
595
+ };
596
+ }
597
+ async function createConversationOp(ctx, opts, defaultTitle = "New Conversation") {
598
+ const convId = opts?.conversationId || generateConversationId();
599
+ const title = opts?.title || defaultTitle;
600
+ const created = await ctx.database.write(async () => {
601
+ return await ctx.conversationsCollection.create((conv) => {
602
+ conv._setRaw("conversation_id", convId);
603
+ conv._setRaw("title", title);
604
+ conv._setRaw("is_deleted", false);
605
+ });
606
+ });
607
+ return conversationToStored(created);
608
+ }
609
+ async function getConversationOp(ctx, id) {
610
+ const results = await ctx.conversationsCollection.query(Q.where("conversation_id", id), Q.where("is_deleted", false)).fetch();
611
+ return results.length > 0 ? conversationToStored(results[0]) : null;
612
+ }
613
+ async function getConversationsOp(ctx) {
614
+ const results = await ctx.conversationsCollection.query(Q.where("is_deleted", false), Q.sortBy("created_at", Q.desc)).fetch();
615
+ return results.map(conversationToStored);
616
+ }
617
+ async function updateConversationTitleOp(ctx, id, title) {
618
+ const results = await ctx.conversationsCollection.query(Q.where("conversation_id", id), Q.where("is_deleted", false)).fetch();
619
+ if (results.length > 0) {
620
+ await ctx.database.write(async () => {
621
+ await results[0].update((conv) => {
622
+ conv._setRaw("title", title);
623
+ });
624
+ });
625
+ return true;
626
+ }
627
+ return false;
628
+ }
629
+ async function deleteConversationOp(ctx, id) {
630
+ const results = await ctx.conversationsCollection.query(Q.where("conversation_id", id), Q.where("is_deleted", false)).fetch();
631
+ if (results.length > 0) {
632
+ await ctx.database.write(async () => {
633
+ await results[0].update((conv) => {
634
+ conv._setRaw("is_deleted", true);
635
+ });
636
+ });
637
+ return true;
638
+ }
639
+ return false;
640
+ }
641
+ async function getMessagesOp(ctx, convId) {
642
+ const results = await ctx.messagesCollection.query(Q.where("conversation_id", convId), Q.sortBy("message_id", Q.asc)).fetch();
643
+ return results.map(messageToStored);
644
+ }
645
+ async function getMessageCountOp(ctx, convId) {
646
+ return await ctx.messagesCollection.query(Q.where("conversation_id", convId)).fetchCount();
647
+ }
648
+ async function clearMessagesOp(ctx, convId) {
649
+ const messages = await ctx.messagesCollection.query(Q.where("conversation_id", convId)).fetch();
650
+ await ctx.database.write(async () => {
651
+ for (const message of messages) {
652
+ await message.destroyPermanently();
653
+ }
654
+ });
655
+ }
656
+ async function createMessageOp(ctx, opts) {
657
+ const existingCount = await getMessageCountOp(ctx, opts.conversationId);
658
+ const messageId = existingCount + 1;
659
+ const created = await ctx.database.write(async () => {
660
+ return await ctx.messagesCollection.create((msg) => {
661
+ msg._setRaw("message_id", messageId);
662
+ msg._setRaw("conversation_id", opts.conversationId);
663
+ msg._setRaw("role", opts.role);
664
+ msg._setRaw("content", opts.content);
665
+ if (opts.model) msg._setRaw("model", opts.model);
666
+ if (opts.files) msg._setRaw("files", JSON.stringify(opts.files));
667
+ if (opts.usage) msg._setRaw("usage", JSON.stringify(opts.usage));
668
+ if (opts.sources) msg._setRaw("sources", JSON.stringify(opts.sources));
669
+ if (opts.responseDuration !== void 0)
670
+ msg._setRaw("response_duration", opts.responseDuration);
671
+ if (opts.vector) msg._setRaw("vector", JSON.stringify(opts.vector));
672
+ if (opts.embeddingModel)
673
+ msg._setRaw("embedding_model", opts.embeddingModel);
674
+ if (opts.wasStopped) msg._setRaw("was_stopped", opts.wasStopped);
675
+ if (opts.error) msg._setRaw("error", opts.error);
676
+ if (opts.thoughtProcess)
677
+ msg._setRaw("thought_process", JSON.stringify(opts.thoughtProcess));
678
+ if (opts.thinking) msg._setRaw("thinking", opts.thinking);
679
+ });
680
+ });
681
+ return messageToStored(created);
682
+ }
683
+ async function updateMessageErrorOp(ctx, uniqueId, error) {
684
+ let message;
685
+ try {
686
+ message = await ctx.messagesCollection.find(uniqueId);
687
+ } catch {
688
+ return null;
689
+ }
690
+ await ctx.database.write(async () => {
691
+ await message.update((msg) => {
692
+ msg._setRaw("error", error);
693
+ });
694
+ });
695
+ return messageToStored(message);
696
+ }
697
+ async function updateMessageOp(ctx, uniqueId, opts) {
698
+ let message;
699
+ try {
700
+ message = await ctx.messagesCollection.find(uniqueId);
701
+ } catch {
702
+ return null;
703
+ }
704
+ await ctx.database.write(async () => {
705
+ await message.update((msg) => {
706
+ if (opts.content !== void 0) msg._setRaw("content", opts.content);
707
+ if (opts.model !== void 0) msg._setRaw("model", opts.model);
708
+ if (opts.files !== void 0)
709
+ msg._setRaw("files", JSON.stringify(opts.files));
710
+ if (opts.usage !== void 0)
711
+ msg._setRaw("usage", JSON.stringify(opts.usage));
712
+ if (opts.sources !== void 0)
713
+ msg._setRaw("sources", JSON.stringify(opts.sources));
714
+ if (opts.responseDuration !== void 0)
715
+ msg._setRaw("response_duration", opts.responseDuration);
716
+ if (opts.vector !== void 0)
717
+ msg._setRaw("vector", JSON.stringify(opts.vector));
718
+ if (opts.embeddingModel !== void 0)
719
+ msg._setRaw("embedding_model", opts.embeddingModel);
720
+ if (opts.wasStopped !== void 0)
721
+ msg._setRaw("was_stopped", opts.wasStopped);
722
+ if (opts.error !== void 0)
723
+ msg._setRaw("error", opts.error === null ? "" : opts.error);
724
+ if (opts.thoughtProcess !== void 0)
725
+ msg._setRaw("thought_process", JSON.stringify(opts.thoughtProcess));
726
+ if (opts.thinking !== void 0)
727
+ msg._setRaw("thinking", opts.thinking === null ? "" : opts.thinking);
728
+ });
729
+ });
730
+ return messageToStored(message);
731
+ }
732
+
733
+ // src/expo/useChatStorage.ts
734
+ function storedToLlmapiMessage(stored) {
735
+ const content = [
736
+ { type: "text", text: stored.content }
737
+ ];
738
+ if (stored.files?.length) {
739
+ for (const file of stored.files) {
740
+ if (file.url) {
741
+ content.push({
742
+ type: "image_url",
743
+ image_url: { url: file.url }
744
+ });
745
+ }
746
+ }
747
+ }
748
+ return {
749
+ role: stored.role,
750
+ content
751
+ };
752
+ }
753
+ function useChatStorage(options) {
754
+ const {
755
+ database,
756
+ conversationId: initialConversationId,
757
+ autoCreateConversation = true,
758
+ defaultConversationTitle = "New Conversation",
759
+ getToken,
760
+ baseUrl,
761
+ onData,
762
+ onFinish,
763
+ onError
764
+ } = options;
765
+ const [currentConversationId, setCurrentConversationId] = useState2(initialConversationId || null);
766
+ const messagesCollection = useMemo(
767
+ () => database.get("history"),
768
+ [database]
769
+ );
770
+ const conversationsCollection = useMemo(
771
+ () => database.get("conversations"),
772
+ [database]
773
+ );
774
+ const storageCtx = useMemo(
775
+ () => ({
776
+ database,
777
+ messagesCollection,
778
+ conversationsCollection
779
+ }),
780
+ [database, messagesCollection, conversationsCollection]
781
+ );
782
+ const {
783
+ isLoading,
784
+ sendMessage: baseSendMessage,
785
+ stop
786
+ } = useChat({
787
+ getToken,
788
+ baseUrl,
789
+ onData,
790
+ onFinish,
791
+ onError
792
+ });
793
+ const createConversation = useCallback2(
794
+ async (opts) => {
795
+ const created = await createConversationOp(
796
+ storageCtx,
797
+ opts,
798
+ defaultConversationTitle
799
+ );
800
+ setCurrentConversationId(created.conversationId);
801
+ return created;
802
+ },
803
+ [storageCtx, defaultConversationTitle]
804
+ );
805
+ const getConversation = useCallback2(
806
+ async (id) => {
807
+ return getConversationOp(storageCtx, id);
808
+ },
809
+ [storageCtx]
810
+ );
811
+ const getConversations = useCallback2(async () => {
812
+ return getConversationsOp(storageCtx);
813
+ }, [storageCtx]);
814
+ const updateConversationTitle = useCallback2(
815
+ async (id, title) => {
816
+ return updateConversationTitleOp(storageCtx, id, title);
817
+ },
818
+ [storageCtx]
819
+ );
820
+ const deleteConversation = useCallback2(
821
+ async (id) => {
822
+ const deleted = await deleteConversationOp(storageCtx, id);
823
+ if (deleted && currentConversationId === id) {
824
+ setCurrentConversationId(null);
825
+ }
826
+ return deleted;
827
+ },
828
+ [storageCtx, currentConversationId]
829
+ );
830
+ const getMessages = useCallback2(
831
+ async (convId) => {
832
+ return getMessagesOp(storageCtx, convId);
833
+ },
834
+ [storageCtx]
835
+ );
836
+ const getMessageCount = useCallback2(
837
+ async (convId) => {
838
+ return getMessageCountOp(storageCtx, convId);
839
+ },
840
+ [storageCtx]
841
+ );
842
+ const clearMessages = useCallback2(
843
+ async (convId) => {
844
+ return clearMessagesOp(storageCtx, convId);
845
+ },
846
+ [storageCtx]
847
+ );
848
+ const updateMessage = useCallback2(
849
+ async (uniqueId, options2) => {
850
+ return updateMessageOp(storageCtx, uniqueId, options2);
851
+ },
852
+ [storageCtx]
853
+ );
854
+ const extractSourcesFromAssistantMessage = useCallback2(
855
+ (assistantMessage) => {
856
+ try {
857
+ const extractedSources = [];
858
+ const seenUrls = /* @__PURE__ */ new Set();
859
+ if (assistantMessage.sources) {
860
+ for (const source of assistantMessage.sources) {
861
+ if (source.url) {
862
+ seenUrls.add(source.url);
863
+ }
864
+ extractedSources.push(source);
865
+ }
866
+ }
867
+ const content = assistantMessage.content;
868
+ if (!content) {
869
+ return extractedSources;
870
+ }
871
+ const markdownLinkRegex = /\[([^\]]*)\]\(([^()]*(?:\([^()]*\)[^()]*)*)\)/g;
872
+ const plainUrlRegex = /https?:\/\/[^\s<>\[\]()'"]+/g;
873
+ let match;
874
+ while ((match = markdownLinkRegex.exec(content)) !== null) {
875
+ const title = match[1].trim();
876
+ const url = match[2].trim();
877
+ if (url && !seenUrls.has(url)) {
878
+ seenUrls.add(url);
879
+ extractedSources.push({
880
+ title: title || void 0,
881
+ url
882
+ });
883
+ }
884
+ }
885
+ while ((match = plainUrlRegex.exec(content)) !== null) {
886
+ const url = match[0].replace(/[.,;:!?]+$/, "").trim();
887
+ if (url && !seenUrls.has(url)) {
888
+ seenUrls.add(url);
889
+ try {
890
+ const urlObj = new URL(url);
891
+ extractedSources.push({
892
+ title: urlObj.hostname,
893
+ url
894
+ });
895
+ } catch {
896
+ extractedSources.push({
897
+ url
898
+ });
899
+ }
900
+ }
901
+ }
902
+ return extractedSources;
903
+ } catch {
904
+ return [];
905
+ }
906
+ },
907
+ []
908
+ );
909
+ const ensureConversation = useCallback2(async () => {
910
+ if (currentConversationId) {
911
+ const existing = await getConversation(currentConversationId);
912
+ if (existing) {
913
+ return currentConversationId;
914
+ }
915
+ if (autoCreateConversation) {
916
+ const newConv = await createConversation({
917
+ conversationId: currentConversationId
918
+ });
919
+ return newConv.conversationId;
920
+ }
921
+ }
922
+ if (autoCreateConversation) {
923
+ const newConv = await createConversation();
924
+ return newConv.conversationId;
925
+ }
926
+ throw new Error(
927
+ "No conversation ID provided and autoCreateConversation is disabled"
928
+ );
929
+ }, [
930
+ currentConversationId,
931
+ getConversation,
932
+ autoCreateConversation,
933
+ createConversation
934
+ ]);
935
+ const sendMessage = useCallback2(
936
+ async (args) => {
937
+ const {
938
+ content,
939
+ model,
940
+ messages: providedMessages,
941
+ includeHistory = true,
942
+ maxHistoryMessages = 50,
943
+ files,
944
+ onData: perRequestOnData,
945
+ onThinking: perRequestOnThinking,
946
+ sources,
947
+ thoughtProcess,
948
+ // Responses API options
949
+ store,
950
+ previousResponseId,
951
+ serverConversation,
952
+ temperature,
953
+ maxOutputTokens,
954
+ tools,
955
+ toolChoice,
956
+ reasoning,
957
+ thinking
958
+ } = args;
959
+ let convId;
960
+ try {
961
+ convId = await ensureConversation();
962
+ } catch (err) {
963
+ return {
964
+ data: null,
965
+ error: err instanceof Error ? err.message : "Failed to ensure conversation"
966
+ };
967
+ }
968
+ let messagesToSend = [];
969
+ if (includeHistory && !providedMessages) {
970
+ const storedMessages = await getMessages(convId);
971
+ const validMessages = storedMessages.filter((msg) => !msg.error);
972
+ const limitedMessages = validMessages.slice(-maxHistoryMessages);
973
+ messagesToSend = limitedMessages.map(storedToLlmapiMessage);
974
+ } else if (providedMessages) {
975
+ messagesToSend = providedMessages;
976
+ }
977
+ const userMessageContent = [
978
+ { type: "text", text: content }
979
+ ];
980
+ if (files?.length) {
981
+ for (const file of files) {
982
+ if (file.url) {
983
+ userMessageContent.push({
984
+ type: "image_url",
985
+ image_url: { url: file.url }
986
+ });
987
+ }
988
+ }
989
+ }
990
+ const userMessage = {
991
+ role: "user",
992
+ content: userMessageContent
993
+ };
994
+ messagesToSend.push(userMessage);
995
+ const sanitizedFiles = files?.map((file) => ({
996
+ id: file.id,
997
+ name: file.name,
998
+ type: file.type,
999
+ size: file.size,
1000
+ // Only keep URL if it's not a data URI (e.g., external URLs)
1001
+ url: file.url && !file.url.startsWith("data:") ? file.url : void 0
1002
+ }));
1003
+ let storedUserMessage;
1004
+ try {
1005
+ storedUserMessage = await createMessageOp(storageCtx, {
1006
+ conversationId: convId,
1007
+ role: "user",
1008
+ content,
1009
+ files: sanitizedFiles,
1010
+ model
1011
+ });
1012
+ } catch (err) {
1013
+ return {
1014
+ data: null,
1015
+ error: err instanceof Error ? err.message : "Failed to store user message"
1016
+ };
1017
+ }
1018
+ const startTime = Date.now();
1019
+ const result = await baseSendMessage({
1020
+ messages: messagesToSend,
1021
+ model,
1022
+ onData: perRequestOnData,
1023
+ onThinking: perRequestOnThinking,
1024
+ // Responses API options
1025
+ store,
1026
+ previousResponseId,
1027
+ conversation: serverConversation,
1028
+ temperature,
1029
+ maxOutputTokens,
1030
+ tools,
1031
+ toolChoice,
1032
+ reasoning,
1033
+ thinking
1034
+ });
1035
+ const responseDuration = (Date.now() - startTime) / 1e3;
1036
+ if (result.error || !result.data) {
1037
+ const abortedResult = result;
1038
+ if (abortedResult.error === "Request aborted") {
1039
+ const assistantContent2 = abortedResult.data?.output?.[0]?.content?.map((part) => part.text || "").join("") || "";
1040
+ const responseModel = abortedResult.data?.model || model || "";
1041
+ let storedAssistantMessage2;
1042
+ try {
1043
+ storedAssistantMessage2 = await createMessageOp(storageCtx, {
1044
+ conversationId: convId,
1045
+ role: "assistant",
1046
+ content: assistantContent2,
1047
+ model: responseModel,
1048
+ usage: convertUsageToStored(abortedResult.data?.usage),
1049
+ responseDuration,
1050
+ wasStopped: true,
1051
+ sources,
1052
+ thoughtProcess: finalizeThoughtProcess(thoughtProcess)
1053
+ });
1054
+ const responseData2 = abortedResult.data || {
1055
+ id: `aborted-${Date.now()}`,
1056
+ model: responseModel,
1057
+ object: "response",
1058
+ output: [{
1059
+ type: "message",
1060
+ role: "assistant",
1061
+ content: [{ type: "output_text", text: assistantContent2 }],
1062
+ status: "completed"
1063
+ }],
1064
+ usage: void 0
1065
+ };
1066
+ return {
1067
+ data: responseData2,
1068
+ error: null,
1069
+ // Treat as success to the caller
1070
+ userMessage: storedUserMessage,
1071
+ assistantMessage: storedAssistantMessage2
1072
+ };
1073
+ } catch {
1074
+ return {
1075
+ data: null,
1076
+ error: "Request aborted",
1077
+ userMessage: storedUserMessage
1078
+ };
1079
+ }
1080
+ }
1081
+ const errorMessage = result.error || "No response data received";
1082
+ try {
1083
+ await updateMessageErrorOp(
1084
+ storageCtx,
1085
+ storedUserMessage.uniqueId,
1086
+ errorMessage
1087
+ );
1088
+ await createMessageOp(storageCtx, {
1089
+ conversationId: convId,
1090
+ role: "assistant",
1091
+ content: "",
1092
+ model: model || "",
1093
+ responseDuration,
1094
+ sources,
1095
+ thoughtProcess: finalizeThoughtProcess(thoughtProcess),
1096
+ error: errorMessage
1097
+ });
1098
+ } catch {
1099
+ }
1100
+ return {
1101
+ data: null,
1102
+ error: errorMessage,
1103
+ userMessage: { ...storedUserMessage, error: errorMessage }
1104
+ };
1105
+ }
1106
+ const responseData = result.data;
1107
+ const messageOutput = responseData.output?.find(
1108
+ (item) => item.type === "message"
1109
+ );
1110
+ const assistantContent = messageOutput?.content?.map((part) => part.text || "").join("") || "";
1111
+ const reasoningOutput = responseData.output?.find(
1112
+ (item) => item.type === "reasoning"
1113
+ );
1114
+ const thinkingContent = reasoningOutput?.content?.map((part) => part.text || "").join("") || void 0;
1115
+ const combinedSources = extractSourcesFromAssistantMessage({
1116
+ content: assistantContent,
1117
+ sources
1118
+ });
1119
+ let storedAssistantMessage;
1120
+ try {
1121
+ storedAssistantMessage = await createMessageOp(storageCtx, {
1122
+ conversationId: convId,
1123
+ role: "assistant",
1124
+ content: assistantContent,
1125
+ model: responseData.model || model,
1126
+ usage: convertUsageToStored(responseData.usage),
1127
+ responseDuration,
1128
+ sources: combinedSources,
1129
+ thoughtProcess: finalizeThoughtProcess(thoughtProcess),
1130
+ thinking: thinkingContent
1131
+ });
1132
+ } catch (err) {
1133
+ return {
1134
+ data: null,
1135
+ error: err instanceof Error ? err.message : "Failed to store assistant message",
1136
+ userMessage: storedUserMessage
1137
+ };
1138
+ }
1139
+ return {
1140
+ data: responseData,
1141
+ error: null,
1142
+ userMessage: storedUserMessage,
1143
+ assistantMessage: storedAssistantMessage
1144
+ };
1145
+ },
1146
+ [ensureConversation, getMessages, storageCtx, baseSendMessage]
1147
+ );
1148
+ return {
1149
+ isLoading,
1150
+ sendMessage,
1151
+ stop,
1152
+ conversationId: currentConversationId,
1153
+ setConversationId: setCurrentConversationId,
1154
+ createConversation,
1155
+ getConversation,
1156
+ getConversations,
1157
+ updateConversationTitle,
1158
+ deleteConversation,
1159
+ getMessages,
1160
+ getMessageCount,
1161
+ clearMessages,
1162
+ extractSourcesFromAssistantMessage,
1163
+ updateMessage
1164
+ };
1165
+ }
1166
+
1167
+ // src/react/useImageGeneration.ts
1168
+ import { useCallback as useCallback3, useEffect as useEffect2, useRef as useRef2, useState as useState3 } from "react";
1169
+
1170
+ // src/client/core/bodySerializer.gen.ts
1171
+ var jsonBodySerializer = {
1172
+ bodySerializer: (body) => JSON.stringify(
1173
+ body,
1174
+ (_key, value) => typeof value === "bigint" ? value.toString() : value
1175
+ )
1176
+ };
1177
+
1178
+ // src/client/core/params.gen.ts
1179
+ var extraPrefixesMap = {
1180
+ $body_: "body",
1181
+ $headers_: "headers",
1182
+ $path_: "path",
1183
+ $query_: "query"
1184
+ };
1185
+ var extraPrefixes = Object.entries(extraPrefixesMap);
1186
+
1187
+ // src/client/core/serverSentEvents.gen.ts
1188
+ var createSseClient = ({
1189
+ onRequest,
1190
+ onSseError,
1191
+ onSseEvent,
1192
+ responseTransformer,
1193
+ responseValidator,
1194
+ sseDefaultRetryDelay,
1195
+ sseMaxRetryAttempts,
1196
+ sseMaxRetryDelay,
1197
+ sseSleepFn,
1198
+ url,
1199
+ ...options
1200
+ }) => {
1201
+ let lastEventId;
1202
+ const sleep = sseSleepFn ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
1203
+ const createStream = async function* () {
1204
+ let retryDelay = sseDefaultRetryDelay ?? 3e3;
1205
+ let attempt = 0;
1206
+ const signal = options.signal ?? new AbortController().signal;
1207
+ while (true) {
1208
+ if (signal.aborted) break;
1209
+ attempt++;
1210
+ const headers = options.headers instanceof Headers ? options.headers : new Headers(options.headers);
1211
+ if (lastEventId !== void 0) {
1212
+ headers.set("Last-Event-ID", lastEventId);
1213
+ }
1214
+ try {
1215
+ const requestInit = {
1216
+ redirect: "follow",
1217
+ ...options,
1218
+ body: options.serializedBody,
1219
+ headers,
1220
+ signal
1221
+ };
1222
+ let request = new Request(url, requestInit);
1223
+ if (onRequest) {
1224
+ request = await onRequest(url, requestInit);
1225
+ }
1226
+ const _fetch = options.fetch ?? globalThis.fetch;
1227
+ const response = await _fetch(request);
1228
+ if (!response.ok)
1229
+ throw new Error(
1230
+ `SSE failed: ${response.status} ${response.statusText}`
1231
+ );
1232
+ if (!response.body) throw new Error("No body in SSE response");
1233
+ const reader = response.body.pipeThrough(new TextDecoderStream()).getReader();
1234
+ let buffer = "";
1235
+ const abortHandler = () => {
1236
+ try {
1237
+ reader.cancel();
1238
+ } catch {
1239
+ }
1240
+ };
1241
+ signal.addEventListener("abort", abortHandler);
1242
+ try {
1243
+ while (true) {
1244
+ const { done, value } = await reader.read();
1245
+ if (done) break;
1246
+ buffer += value;
1247
+ const chunks = buffer.split("\n\n");
1248
+ buffer = chunks.pop() ?? "";
1249
+ for (const chunk of chunks) {
1250
+ const lines = chunk.split("\n");
1251
+ const dataLines = [];
1252
+ let eventName;
1253
+ for (const line of lines) {
1254
+ if (line.startsWith("data:")) {
1255
+ dataLines.push(line.replace(/^data:\s*/, ""));
1256
+ } else if (line.startsWith("event:")) {
1257
+ eventName = line.replace(/^event:\s*/, "");
1258
+ } else if (line.startsWith("id:")) {
1259
+ lastEventId = line.replace(/^id:\s*/, "");
1260
+ } else if (line.startsWith("retry:")) {
1261
+ const parsed = Number.parseInt(
1262
+ line.replace(/^retry:\s*/, ""),
1263
+ 10
1264
+ );
1265
+ if (!Number.isNaN(parsed)) {
1266
+ retryDelay = parsed;
1267
+ }
1268
+ }
1269
+ }
1270
+ let data;
1271
+ let parsedJson = false;
1272
+ if (dataLines.length) {
1273
+ const rawData = dataLines.join("\n");
1274
+ try {
1275
+ data = JSON.parse(rawData);
1276
+ parsedJson = true;
1277
+ } catch {
1278
+ data = rawData;
1279
+ }
1280
+ }
1281
+ if (parsedJson) {
1282
+ if (responseValidator) {
1283
+ await responseValidator(data);
1284
+ }
1285
+ if (responseTransformer) {
1286
+ data = await responseTransformer(data);
1287
+ }
1288
+ }
1289
+ onSseEvent?.({
1290
+ data,
1291
+ event: eventName,
1292
+ id: lastEventId,
1293
+ retry: retryDelay
1294
+ });
1295
+ if (dataLines.length) {
1296
+ yield data;
1297
+ }
1298
+ }
1299
+ }
1300
+ } finally {
1301
+ signal.removeEventListener("abort", abortHandler);
1302
+ reader.releaseLock();
1303
+ }
1304
+ break;
1305
+ } catch (error) {
1306
+ onSseError?.(error);
1307
+ if (sseMaxRetryAttempts !== void 0 && attempt >= sseMaxRetryAttempts) {
1308
+ break;
1309
+ }
1310
+ const backoff = Math.min(
1311
+ retryDelay * 2 ** (attempt - 1),
1312
+ sseMaxRetryDelay ?? 3e4
1313
+ );
1314
+ await sleep(backoff);
1315
+ }
1316
+ }
1317
+ };
1318
+ const stream = createStream();
1319
+ return { stream };
1320
+ };
1321
+
1322
+ // src/client/core/pathSerializer.gen.ts
1323
+ var separatorArrayExplode = (style) => {
1324
+ switch (style) {
1325
+ case "label":
1326
+ return ".";
1327
+ case "matrix":
1328
+ return ";";
1329
+ case "simple":
1330
+ return ",";
1331
+ default:
1332
+ return "&";
1333
+ }
1334
+ };
1335
+ var separatorArrayNoExplode = (style) => {
1336
+ switch (style) {
1337
+ case "form":
1338
+ return ",";
1339
+ case "pipeDelimited":
1340
+ return "|";
1341
+ case "spaceDelimited":
1342
+ return "%20";
1343
+ default:
1344
+ return ",";
1345
+ }
1346
+ };
1347
+ var separatorObjectExplode = (style) => {
1348
+ switch (style) {
1349
+ case "label":
1350
+ return ".";
1351
+ case "matrix":
1352
+ return ";";
1353
+ case "simple":
1354
+ return ",";
1355
+ default:
1356
+ return "&";
1357
+ }
1358
+ };
1359
+ var serializeArrayParam = ({
1360
+ allowReserved,
1361
+ explode,
1362
+ name,
1363
+ style,
1364
+ value
1365
+ }) => {
1366
+ if (!explode) {
1367
+ const joinedValues2 = (allowReserved ? value : value.map((v) => encodeURIComponent(v))).join(separatorArrayNoExplode(style));
1368
+ switch (style) {
1369
+ case "label":
1370
+ return `.${joinedValues2}`;
1371
+ case "matrix":
1372
+ return `;${name}=${joinedValues2}`;
1373
+ case "simple":
1374
+ return joinedValues2;
1375
+ default:
1376
+ return `${name}=${joinedValues2}`;
1377
+ }
1378
+ }
1379
+ const separator = separatorArrayExplode(style);
1380
+ const joinedValues = value.map((v) => {
1381
+ if (style === "label" || style === "simple") {
1382
+ return allowReserved ? v : encodeURIComponent(v);
1383
+ }
1384
+ return serializePrimitiveParam({
1385
+ allowReserved,
1386
+ name,
1387
+ value: v
1388
+ });
1389
+ }).join(separator);
1390
+ return style === "label" || style === "matrix" ? separator + joinedValues : joinedValues;
1391
+ };
1392
+ var serializePrimitiveParam = ({
1393
+ allowReserved,
1394
+ name,
1395
+ value
1396
+ }) => {
1397
+ if (value === void 0 || value === null) {
1398
+ return "";
1399
+ }
1400
+ if (typeof value === "object") {
1401
+ throw new Error(
1402
+ "Deeply-nested arrays/objects aren\u2019t supported. Provide your own `querySerializer()` to handle these."
1403
+ );
1404
+ }
1405
+ return `${name}=${allowReserved ? value : encodeURIComponent(value)}`;
1406
+ };
1407
+ var serializeObjectParam = ({
1408
+ allowReserved,
1409
+ explode,
1410
+ name,
1411
+ style,
1412
+ value,
1413
+ valueOnly
1414
+ }) => {
1415
+ if (value instanceof Date) {
1416
+ return valueOnly ? value.toISOString() : `${name}=${value.toISOString()}`;
1417
+ }
1418
+ if (style !== "deepObject" && !explode) {
1419
+ let values = [];
1420
+ Object.entries(value).forEach(([key, v]) => {
1421
+ values = [
1422
+ ...values,
1423
+ key,
1424
+ allowReserved ? v : encodeURIComponent(v)
1425
+ ];
1426
+ });
1427
+ const joinedValues2 = values.join(",");
1428
+ switch (style) {
1429
+ case "form":
1430
+ return `${name}=${joinedValues2}`;
1431
+ case "label":
1432
+ return `.${joinedValues2}`;
1433
+ case "matrix":
1434
+ return `;${name}=${joinedValues2}`;
1435
+ default:
1436
+ return joinedValues2;
1437
+ }
1438
+ }
1439
+ const separator = separatorObjectExplode(style);
1440
+ const joinedValues = Object.entries(value).map(
1441
+ ([key, v]) => serializePrimitiveParam({
1442
+ allowReserved,
1443
+ name: style === "deepObject" ? `${name}[${key}]` : key,
1444
+ value: v
1445
+ })
1446
+ ).join(separator);
1447
+ return style === "label" || style === "matrix" ? separator + joinedValues : joinedValues;
1448
+ };
1449
+
1450
+ // src/client/core/utils.gen.ts
1451
+ function getValidRequestBody(options) {
1452
+ const hasBody = options.body !== void 0;
1453
+ const isSerializedBody = hasBody && options.bodySerializer;
1454
+ if (isSerializedBody) {
1455
+ if ("serializedBody" in options) {
1456
+ const hasSerializedBody = options.serializedBody !== void 0 && options.serializedBody !== "";
1457
+ return hasSerializedBody ? options.serializedBody : null;
1458
+ }
1459
+ return options.body !== "" ? options.body : null;
1460
+ }
1461
+ if (hasBody) {
1462
+ return options.body;
1463
+ }
1464
+ return void 0;
1465
+ }
1466
+
1467
+ // src/client/core/auth.gen.ts
1468
+ var getAuthToken = async (auth, callback) => {
1469
+ const token = typeof callback === "function" ? await callback(auth) : callback;
1470
+ if (!token) {
1471
+ return;
1472
+ }
1473
+ if (auth.scheme === "bearer") {
1474
+ return `Bearer ${token}`;
1475
+ }
1476
+ if (auth.scheme === "basic") {
1477
+ return `Basic ${btoa(token)}`;
1478
+ }
1479
+ return token;
1480
+ };
1481
+
1482
+ // src/client/client/utils.gen.ts
1483
+ var PATH_PARAM_RE = /\{[^{}]+\}/g;
1484
+ var defaultPathSerializer = ({ path, url: _url }) => {
1485
+ let url = _url;
1486
+ const matches = _url.match(PATH_PARAM_RE);
1487
+ if (matches) {
1488
+ for (const match of matches) {
1489
+ let explode = false;
1490
+ let name = match.substring(1, match.length - 1);
1491
+ let style = "simple";
1492
+ if (name.endsWith("*")) {
1493
+ explode = true;
1494
+ name = name.substring(0, name.length - 1);
1495
+ }
1496
+ if (name.startsWith(".")) {
1497
+ name = name.substring(1);
1498
+ style = "label";
1499
+ } else if (name.startsWith(";")) {
1500
+ name = name.substring(1);
1501
+ style = "matrix";
1502
+ }
1503
+ const value = path[name];
1504
+ if (value === void 0 || value === null) {
1505
+ continue;
1506
+ }
1507
+ if (Array.isArray(value)) {
1508
+ url = url.replace(
1509
+ match,
1510
+ serializeArrayParam({ explode, name, style, value })
1511
+ );
1512
+ continue;
1513
+ }
1514
+ if (typeof value === "object") {
1515
+ url = url.replace(
1516
+ match,
1517
+ serializeObjectParam({
1518
+ explode,
1519
+ name,
1520
+ style,
1521
+ value,
1522
+ valueOnly: true
1523
+ })
1524
+ );
1525
+ continue;
1526
+ }
1527
+ if (style === "matrix") {
1528
+ url = url.replace(
1529
+ match,
1530
+ `;${serializePrimitiveParam({
1531
+ name,
1532
+ value
1533
+ })}`
1534
+ );
1535
+ continue;
1536
+ }
1537
+ const replaceValue = encodeURIComponent(
1538
+ style === "label" ? `.${value}` : value
1539
+ );
1540
+ url = url.replace(match, replaceValue);
1541
+ }
1542
+ }
1543
+ return url;
1544
+ };
1545
+ var createQuerySerializer = ({
1546
+ parameters = {},
1547
+ ...args
1548
+ } = {}) => {
1549
+ const querySerializer = (queryParams) => {
1550
+ const search = [];
1551
+ if (queryParams && typeof queryParams === "object") {
1552
+ for (const name in queryParams) {
1553
+ const value = queryParams[name];
1554
+ if (value === void 0 || value === null) {
1555
+ continue;
1556
+ }
1557
+ const options = parameters[name] || args;
1558
+ if (Array.isArray(value)) {
1559
+ const serializedArray = serializeArrayParam({
1560
+ allowReserved: options.allowReserved,
1561
+ explode: true,
1562
+ name,
1563
+ style: "form",
1564
+ value,
1565
+ ...options.array
1566
+ });
1567
+ if (serializedArray) search.push(serializedArray);
1568
+ } else if (typeof value === "object") {
1569
+ const serializedObject = serializeObjectParam({
1570
+ allowReserved: options.allowReserved,
1571
+ explode: true,
1572
+ name,
1573
+ style: "deepObject",
1574
+ value,
1575
+ ...options.object
1576
+ });
1577
+ if (serializedObject) search.push(serializedObject);
1578
+ } else {
1579
+ const serializedPrimitive = serializePrimitiveParam({
1580
+ allowReserved: options.allowReserved,
1581
+ name,
1582
+ value
1583
+ });
1584
+ if (serializedPrimitive) search.push(serializedPrimitive);
1585
+ }
1586
+ }
1587
+ }
1588
+ return search.join("&");
1589
+ };
1590
+ return querySerializer;
1591
+ };
1592
+ var getParseAs = (contentType) => {
1593
+ if (!contentType) {
1594
+ return "stream";
1595
+ }
1596
+ const cleanContent = contentType.split(";")[0]?.trim();
1597
+ if (!cleanContent) {
1598
+ return;
1599
+ }
1600
+ if (cleanContent.startsWith("application/json") || cleanContent.endsWith("+json")) {
1601
+ return "json";
1602
+ }
1603
+ if (cleanContent === "multipart/form-data") {
1604
+ return "formData";
1605
+ }
1606
+ if (["application/", "audio/", "image/", "video/"].some(
1607
+ (type) => cleanContent.startsWith(type)
1608
+ )) {
1609
+ return "blob";
1610
+ }
1611
+ if (cleanContent.startsWith("text/")) {
1612
+ return "text";
1613
+ }
1614
+ return;
1615
+ };
1616
+ var checkForExistence = (options, name) => {
1617
+ if (!name) {
1618
+ return false;
1619
+ }
1620
+ if (options.headers.has(name) || options.query?.[name] || options.headers.get("Cookie")?.includes(`${name}=`)) {
1621
+ return true;
1622
+ }
1623
+ return false;
1624
+ };
1625
+ var setAuthParams = async ({
1626
+ security,
1627
+ ...options
1628
+ }) => {
1629
+ for (const auth of security) {
1630
+ if (checkForExistence(options, auth.name)) {
1631
+ continue;
1632
+ }
1633
+ const token = await getAuthToken(auth, options.auth);
1634
+ if (!token) {
1635
+ continue;
1636
+ }
1637
+ const name = auth.name ?? "Authorization";
1638
+ switch (auth.in) {
1639
+ case "query":
1640
+ if (!options.query) {
1641
+ options.query = {};
1642
+ }
1643
+ options.query[name] = token;
1644
+ break;
1645
+ case "cookie":
1646
+ options.headers.append("Cookie", `${name}=${token}`);
1647
+ break;
1648
+ case "header":
1649
+ default:
1650
+ options.headers.set(name, token);
1651
+ break;
1652
+ }
1653
+ }
1654
+ };
1655
+ var buildUrl = (options) => {
1656
+ const url = getUrl({
1657
+ baseUrl: options.baseUrl,
1658
+ path: options.path,
1659
+ query: options.query,
1660
+ querySerializer: typeof options.querySerializer === "function" ? options.querySerializer : createQuerySerializer(options.querySerializer),
1661
+ url: options.url
1662
+ });
1663
+ return url;
1664
+ };
1665
+ var getUrl = ({
1666
+ baseUrl,
1667
+ path,
1668
+ query,
1669
+ querySerializer,
1670
+ url: _url
1671
+ }) => {
1672
+ const pathUrl = _url.startsWith("/") ? _url : `/${_url}`;
1673
+ let url = (baseUrl ?? "") + pathUrl;
1674
+ if (path) {
1675
+ url = defaultPathSerializer({ path, url });
1676
+ }
1677
+ let search = query ? querySerializer(query) : "";
1678
+ if (search.startsWith("?")) {
1679
+ search = search.substring(1);
1680
+ }
1681
+ if (search) {
1682
+ url += `?${search}`;
1683
+ }
1684
+ return url;
1685
+ };
1686
+ var mergeConfigs = (a, b) => {
1687
+ const config = { ...a, ...b };
1688
+ if (config.baseUrl?.endsWith("/")) {
1689
+ config.baseUrl = config.baseUrl.substring(0, config.baseUrl.length - 1);
1690
+ }
1691
+ config.headers = mergeHeaders(a.headers, b.headers);
1692
+ return config;
1693
+ };
1694
+ var headersEntries = (headers) => {
1695
+ const entries = [];
1696
+ headers.forEach((value, key) => {
1697
+ entries.push([key, value]);
1698
+ });
1699
+ return entries;
1700
+ };
1701
+ var mergeHeaders = (...headers) => {
1702
+ const mergedHeaders = new Headers();
1703
+ for (const header of headers) {
1704
+ if (!header || typeof header !== "object") {
1705
+ continue;
1706
+ }
1707
+ const iterator = header instanceof Headers ? headersEntries(header) : Object.entries(header);
1708
+ for (const [key, value] of iterator) {
1709
+ if (value === null) {
1710
+ mergedHeaders.delete(key);
1711
+ } else if (Array.isArray(value)) {
1712
+ for (const v of value) {
1713
+ mergedHeaders.append(key, v);
1714
+ }
1715
+ } else if (value !== void 0) {
1716
+ mergedHeaders.set(
1717
+ key,
1718
+ typeof value === "object" ? JSON.stringify(value) : value
1719
+ );
1720
+ }
1721
+ }
1722
+ }
1723
+ return mergedHeaders;
1724
+ };
1725
+ var Interceptors = class {
1726
+ constructor() {
1727
+ this.fns = [];
1728
+ }
1729
+ clear() {
1730
+ this.fns = [];
1731
+ }
1732
+ eject(id) {
1733
+ const index = this.getInterceptorIndex(id);
1734
+ if (this.fns[index]) {
1735
+ this.fns[index] = null;
1736
+ }
1737
+ }
1738
+ exists(id) {
1739
+ const index = this.getInterceptorIndex(id);
1740
+ return Boolean(this.fns[index]);
1741
+ }
1742
+ getInterceptorIndex(id) {
1743
+ if (typeof id === "number") {
1744
+ return this.fns[id] ? id : -1;
1745
+ }
1746
+ return this.fns.indexOf(id);
1747
+ }
1748
+ update(id, fn) {
1749
+ const index = this.getInterceptorIndex(id);
1750
+ if (this.fns[index]) {
1751
+ this.fns[index] = fn;
1752
+ return id;
1753
+ }
1754
+ return false;
1755
+ }
1756
+ use(fn) {
1757
+ this.fns.push(fn);
1758
+ return this.fns.length - 1;
1759
+ }
1760
+ };
1761
+ var createInterceptors = () => ({
1762
+ error: new Interceptors(),
1763
+ request: new Interceptors(),
1764
+ response: new Interceptors()
1765
+ });
1766
+ var defaultQuerySerializer = createQuerySerializer({
1767
+ allowReserved: false,
1768
+ array: {
1769
+ explode: true,
1770
+ style: "form"
1771
+ },
1772
+ object: {
1773
+ explode: true,
1774
+ style: "deepObject"
1775
+ }
1776
+ });
1777
+ var defaultHeaders = {
1778
+ "Content-Type": "application/json"
1779
+ };
1780
+ var createConfig = (override = {}) => ({
1781
+ ...jsonBodySerializer,
1782
+ headers: defaultHeaders,
1783
+ parseAs: "auto",
1784
+ querySerializer: defaultQuerySerializer,
1785
+ ...override
1786
+ });
1787
+
1788
+ // src/client/client/client.gen.ts
1789
+ var createClient = (config = {}) => {
1790
+ let _config = mergeConfigs(createConfig(), config);
1791
+ const getConfig = () => ({ ..._config });
1792
+ const setConfig = (config2) => {
1793
+ _config = mergeConfigs(_config, config2);
1794
+ return getConfig();
1795
+ };
1796
+ const interceptors = createInterceptors();
1797
+ const beforeRequest = async (options) => {
1798
+ const opts = {
1799
+ ..._config,
1800
+ ...options,
1801
+ fetch: options.fetch ?? _config.fetch ?? globalThis.fetch,
1802
+ headers: mergeHeaders(_config.headers, options.headers),
1803
+ serializedBody: void 0
1804
+ };
1805
+ if (opts.security) {
1806
+ await setAuthParams({
1807
+ ...opts,
1808
+ security: opts.security
1809
+ });
1810
+ }
1811
+ if (opts.requestValidator) {
1812
+ await opts.requestValidator(opts);
1813
+ }
1814
+ if (opts.body !== void 0 && opts.bodySerializer) {
1815
+ opts.serializedBody = opts.bodySerializer(opts.body);
1816
+ }
1817
+ if (opts.body === void 0 || opts.serializedBody === "") {
1818
+ opts.headers.delete("Content-Type");
1819
+ }
1820
+ const url = buildUrl(opts);
1821
+ return { opts, url };
1822
+ };
1823
+ const request = async (options) => {
1824
+ const { opts, url } = await beforeRequest(options);
1825
+ for (const fn of interceptors.request.fns) {
1826
+ if (fn) {
1827
+ await fn(opts);
1828
+ }
1829
+ }
1830
+ const _fetch = opts.fetch;
1831
+ const requestInit = {
1832
+ ...opts,
1833
+ body: getValidRequestBody(opts)
1834
+ };
1835
+ let response = await _fetch(url, requestInit);
1836
+ for (const fn of interceptors.response.fns) {
1837
+ if (fn) {
1838
+ response = await fn(response, opts);
1839
+ }
1840
+ }
1841
+ const result = {
1842
+ response
1843
+ };
1844
+ if (response.ok) {
1845
+ const parseAs = (opts.parseAs === "auto" ? getParseAs(response.headers.get("Content-Type")) : opts.parseAs) ?? "json";
1846
+ if (response.status === 204 || response.headers.get("Content-Length") === "0") {
1847
+ let emptyData;
1848
+ switch (parseAs) {
1849
+ case "arrayBuffer":
1850
+ case "blob":
1851
+ case "text":
1852
+ emptyData = await response[parseAs]();
1853
+ break;
1854
+ case "formData":
1855
+ emptyData = new FormData();
1856
+ break;
1857
+ case "stream":
1858
+ emptyData = response.body;
1859
+ break;
1860
+ case "json":
1861
+ default:
1862
+ emptyData = {};
1863
+ break;
1864
+ }
1865
+ return {
1866
+ data: emptyData,
1867
+ ...result
1868
+ };
1869
+ }
1870
+ let data;
1871
+ switch (parseAs) {
1872
+ case "arrayBuffer":
1873
+ case "blob":
1874
+ case "formData":
1875
+ case "json":
1876
+ case "text":
1877
+ data = await response[parseAs]();
1878
+ break;
1879
+ case "stream":
1880
+ return {
1881
+ data: response.body,
1882
+ ...result
1883
+ };
1884
+ }
1885
+ if (parseAs === "json") {
1886
+ if (opts.responseValidator) {
1887
+ await opts.responseValidator(data);
1888
+ }
1889
+ if (opts.responseTransformer) {
1890
+ data = await opts.responseTransformer(data);
1891
+ }
1892
+ }
1893
+ return {
1894
+ data,
1895
+ ...result
1896
+ };
1897
+ }
1898
+ const textError = await response.text();
1899
+ let jsonError;
1900
+ try {
1901
+ jsonError = JSON.parse(textError);
1902
+ } catch {
1903
+ }
1904
+ const error = jsonError ?? textError;
1905
+ let finalError = error;
1906
+ for (const fn of interceptors.error.fns) {
1907
+ if (fn) {
1908
+ finalError = await fn(error, response, opts);
1909
+ }
1910
+ }
1911
+ finalError = finalError || {};
1912
+ if (opts.throwOnError) {
1913
+ throw finalError;
1914
+ }
1915
+ return {
1916
+ error: finalError,
1917
+ ...result
1918
+ };
1919
+ };
1920
+ const makeMethodFn = (method) => (options) => request({ ...options, method });
1921
+ const makeSseFn = (method) => async (options) => {
1922
+ const { opts, url } = await beforeRequest(options);
1923
+ return createSseClient({
1924
+ ...opts,
1925
+ body: opts.body,
1926
+ headers: opts.headers,
1927
+ method,
1928
+ onRequest: async (url2, init) => {
1929
+ let request2 = new Request(url2, init);
1930
+ const requestInit = {
1931
+ ...init,
1932
+ method: init.method,
1933
+ url: url2
1934
+ };
1935
+ for (const fn of interceptors.request.fns) {
1936
+ if (fn) {
1937
+ await fn(requestInit);
1938
+ request2 = new Request(requestInit.url, requestInit);
1939
+ }
1940
+ }
1941
+ return request2;
1942
+ },
1943
+ url
1944
+ });
1945
+ };
1946
+ return {
1947
+ buildUrl,
1948
+ connect: makeMethodFn("CONNECT"),
1949
+ delete: makeMethodFn("DELETE"),
1950
+ get: makeMethodFn("GET"),
1951
+ getConfig,
1952
+ head: makeMethodFn("HEAD"),
1953
+ interceptors,
1954
+ options: makeMethodFn("OPTIONS"),
1955
+ patch: makeMethodFn("PATCH"),
1956
+ post: makeMethodFn("POST"),
1957
+ put: makeMethodFn("PUT"),
1958
+ request,
1959
+ setConfig,
1960
+ sse: {
1961
+ connect: makeSseFn("CONNECT"),
1962
+ delete: makeSseFn("DELETE"),
1963
+ get: makeSseFn("GET"),
1964
+ head: makeSseFn("HEAD"),
1965
+ options: makeSseFn("OPTIONS"),
1966
+ patch: makeSseFn("PATCH"),
1967
+ post: makeSseFn("POST"),
1968
+ put: makeSseFn("PUT"),
1969
+ trace: makeSseFn("TRACE")
1970
+ },
1971
+ trace: makeMethodFn("TRACE")
1972
+ };
1973
+ };
1974
+
1975
+ // src/client/client.gen.ts
1976
+ var client = createClient(createClientConfig(createConfig()));
1977
+
1978
+ // src/client/sdk.gen.ts
1979
+ var postApiV1ImagesGenerations = (options) => {
1980
+ return (options.client ?? client).post({
1981
+ url: "/api/v1/images/generations",
1982
+ ...options,
1983
+ headers: {
1984
+ "Content-Type": "application/json",
1985
+ ...options.headers
1986
+ }
1987
+ });
1988
+ };
1989
+ var getApiV1Models = (options) => {
1990
+ return (options?.client ?? client).get({
1991
+ url: "/api/v1/models",
1992
+ ...options
1993
+ });
1994
+ };
1995
+
1996
+ // src/react/useImageGeneration.ts
1997
+ function useImageGeneration(options = {}) {
1998
+ const { getToken, baseUrl = BASE_URL, onFinish, onError } = options;
1999
+ const [isLoading, setIsLoading] = useState3(false);
2000
+ const abortControllerRef = useRef2(null);
2001
+ useEffect2(() => {
2002
+ return () => {
2003
+ if (abortControllerRef.current) {
2004
+ abortControllerRef.current.abort();
2005
+ abortControllerRef.current = null;
2006
+ }
2007
+ };
2008
+ }, []);
2009
+ const stop = useCallback3(() => {
2010
+ if (abortControllerRef.current) {
2011
+ abortControllerRef.current.abort();
2012
+ abortControllerRef.current = null;
2013
+ }
2014
+ }, []);
2015
+ const generateImage = useCallback3(
2016
+ async (args) => {
2017
+ if (abortControllerRef.current) {
2018
+ abortControllerRef.current.abort();
2019
+ }
2020
+ const abortController = new AbortController();
2021
+ abortControllerRef.current = abortController;
2022
+ setIsLoading(true);
2023
+ try {
2024
+ if (!getToken) {
2025
+ throw new Error("Token getter function is required.");
2026
+ }
2027
+ const token = await getToken();
2028
+ if (!token) {
2029
+ throw new Error("No access token available.");
2030
+ }
2031
+ const response = await postApiV1ImagesGenerations({
2032
+ baseUrl,
2033
+ body: args,
2034
+ headers: {
2035
+ Authorization: `Bearer ${token}`
2036
+ },
2037
+ signal: abortController.signal
2038
+ });
2039
+ if (response.error) {
2040
+ const errorMsg = response.error.error || "Failed to generate image";
2041
+ throw new Error(errorMsg);
2042
+ }
2043
+ if (!response.data) {
2044
+ throw new Error("No data received from image generation API");
2045
+ }
2046
+ const result = response.data;
2047
+ if (onFinish) {
2048
+ onFinish(result);
2049
+ }
2050
+ return { data: result, error: null };
2051
+ } catch (err) {
2052
+ if (err instanceof Error && err.name === "AbortError") {
2053
+ return { data: null, error: "Request aborted" };
2054
+ }
2055
+ const errorMsg = err instanceof Error ? err.message : "Failed to generate image.";
2056
+ const errorObj = err instanceof Error ? err : new Error(errorMsg);
2057
+ if (onError) {
2058
+ onError(errorObj);
2059
+ }
2060
+ return { data: null, error: errorMsg };
2061
+ } finally {
2062
+ if (abortControllerRef.current === abortController) {
2063
+ setIsLoading(false);
2064
+ abortControllerRef.current = null;
2065
+ }
2066
+ }
2067
+ },
2068
+ [getToken, baseUrl, onFinish, onError]
2069
+ );
2070
+ return {
2071
+ isLoading,
2072
+ generateImage,
2073
+ stop
2074
+ };
2075
+ }
2076
+
2077
+ // src/react/useModels.ts
2078
+ import { useCallback as useCallback4, useEffect as useEffect3, useRef as useRef3, useState as useState4 } from "react";
2079
+ function useModels(options = {}) {
2080
+ const { getToken, baseUrl = BASE_URL, provider, autoFetch = true } = options;
2081
+ const [models, setModels] = useState4([]);
2082
+ const [isLoading, setIsLoading] = useState4(false);
2083
+ const [error, setError] = useState4(null);
2084
+ const getTokenRef = useRef3(getToken);
2085
+ const baseUrlRef = useRef3(baseUrl);
2086
+ const providerRef = useRef3(provider);
2087
+ const abortControllerRef = useRef3(null);
2088
+ useEffect3(() => {
2089
+ getTokenRef.current = getToken;
2090
+ baseUrlRef.current = baseUrl;
2091
+ providerRef.current = provider;
2092
+ });
2093
+ useEffect3(() => {
2094
+ return () => {
2095
+ if (abortControllerRef.current) {
2096
+ abortControllerRef.current.abort();
2097
+ abortControllerRef.current = null;
2098
+ }
2099
+ };
2100
+ }, []);
2101
+ const fetchModels = useCallback4(async () => {
2102
+ if (abortControllerRef.current) {
2103
+ abortControllerRef.current.abort();
2104
+ }
2105
+ const abortController = new AbortController();
2106
+ abortControllerRef.current = abortController;
2107
+ const signal = abortController.signal;
2108
+ setIsLoading(true);
2109
+ setError(null);
2110
+ try {
2111
+ let token;
2112
+ if (getTokenRef.current) {
2113
+ token = await getTokenRef.current() ?? void 0;
2114
+ }
2115
+ if (signal.aborted) return;
2116
+ const headers = {};
2117
+ if (token) {
2118
+ headers["Authorization"] = `Bearer ${token}`;
2119
+ }
2120
+ let allModels = [];
2121
+ let nextPageToken;
2122
+ do {
2123
+ if (signal.aborted) return;
2124
+ const response = await getApiV1Models({
2125
+ baseUrl: baseUrlRef.current,
2126
+ headers,
2127
+ query: {
2128
+ provider: providerRef.current,
2129
+ page_token: nextPageToken
2130
+ },
2131
+ signal
2132
+ });
2133
+ if (response.error) {
2134
+ const errorMsg = response.error.error ?? "Failed to fetch models";
2135
+ throw new Error(errorMsg);
2136
+ }
2137
+ if (response.data) {
2138
+ const newModels = response.data.data || [];
2139
+ allModels = [...allModels, ...newModels];
2140
+ nextPageToken = response.data.next_page_token;
2141
+ }
2142
+ } while (nextPageToken);
2143
+ if (signal.aborted) return;
2144
+ setModels(allModels);
2145
+ } catch (err) {
2146
+ if (err instanceof Error && err.name === "AbortError") {
2147
+ return;
2148
+ }
2149
+ setError(err instanceof Error ? err : new Error(String(err)));
2150
+ } finally {
2151
+ if (!signal.aborted) {
2152
+ setIsLoading(false);
2153
+ }
2154
+ if (abortControllerRef.current === abortController) {
2155
+ abortControllerRef.current = null;
2156
+ }
2157
+ }
2158
+ }, []);
2159
+ const refetch = useCallback4(async () => {
2160
+ setModels([]);
2161
+ await fetchModels();
2162
+ }, [fetchModels]);
2163
+ const hasFetchedRef = useRef3(false);
2164
+ useEffect3(() => {
2165
+ if (autoFetch && !hasFetchedRef.current) {
2166
+ hasFetchedRef.current = true;
2167
+ fetchModels();
2168
+ }
2169
+ if (!autoFetch) {
2170
+ hasFetchedRef.current = false;
2171
+ }
2172
+ }, [autoFetch, fetchModels]);
2173
+ return {
2174
+ models,
2175
+ isLoading,
2176
+ error,
2177
+ refetch
2178
+ };
2179
+ }
2180
+
2181
+ // src/expo/useMemoryStorage.ts
2182
+ import { useCallback as useCallback5, useState as useState5, useMemo as useMemo2, useRef as useRef4 } from "react";
2183
+ import { postApiV1ChatCompletions } from "@reverbia/sdk";
2184
+
2185
+ // src/lib/db/memory/schema.ts
2186
+ import { appSchema as appSchema2, tableSchema as tableSchema2 } from "@nozbe/watermelondb";
2187
+ var memoryStorageSchema = appSchema2({
2188
+ version: 1,
2189
+ tables: [
2190
+ tableSchema2({
2191
+ name: "memories",
2192
+ columns: [
2193
+ { name: "type", type: "string", isIndexed: true },
2194
+ { name: "namespace", type: "string", isIndexed: true },
2195
+ { name: "key", type: "string", isIndexed: true },
2196
+ { name: "value", type: "string" },
2197
+ { name: "raw_evidence", type: "string" },
2198
+ { name: "confidence", type: "number" },
2199
+ { name: "pii", type: "boolean", isIndexed: true },
2200
+ { name: "composite_key", type: "string", isIndexed: true },
2201
+ { name: "unique_key", type: "string", isIndexed: true },
2202
+ { name: "created_at", type: "number", isIndexed: true },
2203
+ { name: "updated_at", type: "number" },
2204
+ { name: "embedding", type: "string", isOptional: true },
2205
+ { name: "embedding_model", type: "string", isOptional: true },
2206
+ { name: "is_deleted", type: "boolean", isIndexed: true }
2207
+ ]
2208
+ })
2209
+ ]
2210
+ });
2211
+
2212
+ // src/lib/db/memory/models.ts
2213
+ import { Model as Model2 } from "@nozbe/watermelondb";
2214
+ import { field as field2, text as text2, date as date2, json as json2 } from "@nozbe/watermelondb/decorators";
2215
+ var Memory = class extends Model2 {
2216
+ };
2217
+ Memory.table = "memories";
2218
+ __decorateClass([
2219
+ text2("type")
2220
+ ], Memory.prototype, "type", 2);
2221
+ __decorateClass([
2222
+ text2("namespace")
2223
+ ], Memory.prototype, "namespace", 2);
2224
+ __decorateClass([
2225
+ text2("key")
2226
+ ], Memory.prototype, "key", 2);
2227
+ __decorateClass([
2228
+ text2("value")
2229
+ ], Memory.prototype, "value", 2);
2230
+ __decorateClass([
2231
+ text2("raw_evidence")
2232
+ ], Memory.prototype, "rawEvidence", 2);
2233
+ __decorateClass([
2234
+ field2("confidence")
2235
+ ], Memory.prototype, "confidence", 2);
2236
+ __decorateClass([
2237
+ field2("pii")
2238
+ ], Memory.prototype, "pii", 2);
2239
+ __decorateClass([
2240
+ text2("composite_key")
2241
+ ], Memory.prototype, "compositeKey", 2);
2242
+ __decorateClass([
2243
+ text2("unique_key")
2244
+ ], Memory.prototype, "uniqueKey", 2);
2245
+ __decorateClass([
2246
+ date2("created_at")
2247
+ ], Memory.prototype, "createdAt", 2);
2248
+ __decorateClass([
2249
+ date2("updated_at")
2250
+ ], Memory.prototype, "updatedAt", 2);
2251
+ __decorateClass([
2252
+ json2("embedding", (json3) => json3)
2253
+ ], Memory.prototype, "embedding", 2);
2254
+ __decorateClass([
2255
+ text2("embedding_model")
2256
+ ], Memory.prototype, "embeddingModel", 2);
2257
+ __decorateClass([
2258
+ field2("is_deleted")
2259
+ ], Memory.prototype, "isDeleted", 2);
2260
+
2261
+ // src/lib/db/memory/types.ts
2262
+ function generateCompositeKey(namespace, key) {
2263
+ return `${namespace}:${key}`;
2264
+ }
2265
+ function generateUniqueKey(namespace, key, value) {
2266
+ return `${namespace}:${key}:${value}`;
2267
+ }
2268
+ function cosineSimilarity(a, b) {
2269
+ if (a.length !== b.length) {
2270
+ throw new Error("Vectors must have the same length");
2271
+ }
2272
+ let dotProduct = 0;
2273
+ let normA = 0;
2274
+ let normB = 0;
2275
+ for (let i = 0; i < a.length; i++) {
2276
+ dotProduct += a[i] * b[i];
2277
+ normA += a[i] * a[i];
2278
+ normB += b[i] * b[i];
2279
+ }
2280
+ const denominator = Math.sqrt(normA) * Math.sqrt(normB);
2281
+ if (denominator === 0) {
2282
+ return 0;
2283
+ }
2284
+ return dotProduct / denominator;
2285
+ }
2286
+
2287
+ // src/lib/db/memory/operations.ts
2288
+ import { Q as Q2 } from "@nozbe/watermelondb";
2289
+ function memoryToStored(memory) {
2290
+ return {
2291
+ uniqueId: memory.id,
2292
+ type: memory.type,
2293
+ namespace: memory.namespace,
2294
+ key: memory.key,
2295
+ value: memory.value,
2296
+ rawEvidence: memory.rawEvidence,
2297
+ confidence: memory.confidence,
2298
+ pii: memory.pii,
2299
+ compositeKey: memory.compositeKey,
2300
+ uniqueKey: memory.uniqueKey,
2301
+ createdAt: memory.createdAt,
2302
+ updatedAt: memory.updatedAt,
2303
+ embedding: memory.embedding,
2304
+ embeddingModel: memory.embeddingModel,
2305
+ isDeleted: memory.isDeleted
2306
+ };
2307
+ }
2308
+ async function getAllMemoriesOp(ctx) {
2309
+ const results = await ctx.memoriesCollection.query(Q2.where("is_deleted", false), Q2.sortBy("created_at", Q2.desc)).fetch();
2310
+ return results.map(memoryToStored);
2311
+ }
2312
+ async function getMemoryByIdOp(ctx, id) {
2313
+ try {
2314
+ const memory = await ctx.memoriesCollection.find(id);
2315
+ if (memory.isDeleted) return null;
2316
+ return memoryToStored(memory);
2317
+ } catch {
2318
+ return null;
2319
+ }
2320
+ }
2321
+ async function getMemoriesByNamespaceOp(ctx, namespace) {
2322
+ const results = await ctx.memoriesCollection.query(
2323
+ Q2.where("namespace", namespace),
2324
+ Q2.where("is_deleted", false),
2325
+ Q2.sortBy("created_at", Q2.desc)
2326
+ ).fetch();
2327
+ return results.map(memoryToStored);
2328
+ }
2329
+ async function getMemoriesByKeyOp(ctx, namespace, key) {
2330
+ const compositeKey = generateCompositeKey(namespace, key);
2331
+ const results = await ctx.memoriesCollection.query(
2332
+ Q2.where("composite_key", compositeKey),
2333
+ Q2.where("is_deleted", false),
2334
+ Q2.sortBy("created_at", Q2.desc)
2335
+ ).fetch();
2336
+ return results.map(memoryToStored);
2337
+ }
2338
+ async function saveMemoryOp(ctx, opts) {
2339
+ if (!opts.namespace || typeof opts.namespace !== "string") {
2340
+ throw new Error("Namespace is required and must be a string");
2341
+ }
2342
+ if (!opts.key || typeof opts.key !== "string") {
2343
+ throw new Error("Key is required and must be a string");
2344
+ }
2345
+ if (!opts.value || typeof opts.value !== "string") {
2346
+ throw new Error("Value is required and must be a string");
2347
+ }
2348
+ if (!opts.type || typeof opts.type !== "string") {
2349
+ throw new Error("Type is required and must be a string");
2350
+ }
2351
+ if (typeof opts.confidence !== "number" || opts.confidence < 0 || opts.confidence > 1) {
2352
+ throw new Error("Confidence must be a number between 0 and 1");
2353
+ }
2354
+ if (typeof opts.pii !== "boolean") {
2355
+ throw new Error("PII must be a boolean");
2356
+ }
2357
+ const compositeKey = generateCompositeKey(opts.namespace, opts.key);
2358
+ const uniqueKey = generateUniqueKey(opts.namespace, opts.key, opts.value);
2359
+ const result = await ctx.database.write(async () => {
2360
+ const existing = await ctx.memoriesCollection.query(Q2.where("unique_key", uniqueKey)).fetch();
2361
+ if (existing.length > 0) {
2362
+ const existingMemory = existing[0];
2363
+ const shouldPreserveEmbedding = existingMemory.value === opts.value && existingMemory.rawEvidence === opts.rawEvidence && existingMemory.type === opts.type && existingMemory.namespace === opts.namespace && existingMemory.key === opts.key && existingMemory.embedding !== void 0 && existingMemory.embedding.length > 0 && !opts.embedding;
2364
+ await existingMemory.update((mem) => {
2365
+ mem._setRaw("type", opts.type);
2366
+ mem._setRaw("namespace", opts.namespace);
2367
+ mem._setRaw("key", opts.key);
2368
+ mem._setRaw("value", opts.value);
2369
+ mem._setRaw("raw_evidence", opts.rawEvidence);
2370
+ mem._setRaw("confidence", opts.confidence);
2371
+ mem._setRaw("pii", opts.pii);
2372
+ mem._setRaw("composite_key", compositeKey);
2373
+ mem._setRaw("unique_key", uniqueKey);
2374
+ mem._setRaw("is_deleted", false);
2375
+ if (shouldPreserveEmbedding) {
2376
+ } else if (opts.embedding) {
2377
+ mem._setRaw("embedding", JSON.stringify(opts.embedding));
2378
+ if (opts.embeddingModel) {
2379
+ mem._setRaw("embedding_model", opts.embeddingModel);
2380
+ }
2381
+ } else {
2382
+ mem._setRaw("embedding", null);
2383
+ mem._setRaw("embedding_model", null);
2384
+ }
2385
+ });
2386
+ return existingMemory;
2387
+ }
2388
+ return await ctx.memoriesCollection.create((mem) => {
2389
+ mem._setRaw("type", opts.type);
2390
+ mem._setRaw("namespace", opts.namespace);
2391
+ mem._setRaw("key", opts.key);
2392
+ mem._setRaw("value", opts.value);
2393
+ mem._setRaw("raw_evidence", opts.rawEvidence);
2394
+ mem._setRaw("confidence", opts.confidence);
2395
+ mem._setRaw("pii", opts.pii);
2396
+ mem._setRaw("composite_key", compositeKey);
2397
+ mem._setRaw("unique_key", uniqueKey);
2398
+ mem._setRaw("is_deleted", false);
2399
+ if (opts.embedding) {
2400
+ mem._setRaw("embedding", JSON.stringify(opts.embedding));
2401
+ if (opts.embeddingModel) {
2402
+ mem._setRaw("embedding_model", opts.embeddingModel);
2403
+ }
2404
+ }
2405
+ });
2406
+ });
2407
+ return memoryToStored(result);
2408
+ }
2409
+ async function saveMemoriesOp(ctx, memories) {
2410
+ const results = [];
2411
+ for (const memory of memories) {
2412
+ const saved = await saveMemoryOp(ctx, memory);
2413
+ results.push(saved);
2414
+ }
2415
+ return results;
2416
+ }
2417
+ async function updateMemoryOp(ctx, id, updates) {
2418
+ let memory;
2419
+ try {
2420
+ memory = await ctx.memoriesCollection.find(id);
2421
+ } catch {
2422
+ return { ok: false, reason: "not_found" };
2423
+ }
2424
+ if (memory.isDeleted) {
2425
+ return { ok: false, reason: "not_found" };
2426
+ }
2427
+ const newNamespace = updates.namespace ?? memory.namespace;
2428
+ const newKey = updates.key ?? memory.key;
2429
+ const newValue = updates.value ?? memory.value;
2430
+ const newCompositeKey = generateCompositeKey(newNamespace, newKey);
2431
+ const newUniqueKey = generateUniqueKey(newNamespace, newKey, newValue);
2432
+ if (newUniqueKey !== memory.uniqueKey) {
2433
+ const existing = await ctx.memoriesCollection.query(Q2.where("unique_key", newUniqueKey), Q2.where("is_deleted", false)).fetch();
2434
+ if (existing.length > 0) {
2435
+ return { ok: false, reason: "conflict", conflictingKey: newUniqueKey };
2436
+ }
2437
+ }
2438
+ try {
2439
+ const updated = await ctx.database.write(async () => {
2440
+ await memory.update((mem) => {
2441
+ if (updates.type !== void 0) mem._setRaw("type", updates.type);
2442
+ if (updates.namespace !== void 0)
2443
+ mem._setRaw("namespace", updates.namespace);
2444
+ if (updates.key !== void 0) mem._setRaw("key", updates.key);
2445
+ if (updates.value !== void 0) mem._setRaw("value", updates.value);
2446
+ if (updates.rawEvidence !== void 0)
2447
+ mem._setRaw("raw_evidence", updates.rawEvidence);
2448
+ if (updates.confidence !== void 0)
2449
+ mem._setRaw("confidence", updates.confidence);
2450
+ if (updates.pii !== void 0) mem._setRaw("pii", updates.pii);
2451
+ if (updates.namespace !== void 0 || updates.key !== void 0 || updates.value !== void 0) {
2452
+ mem._setRaw("composite_key", newCompositeKey);
2453
+ mem._setRaw("unique_key", newUniqueKey);
2454
+ }
2455
+ if (updates.embedding !== void 0) {
2456
+ mem._setRaw(
2457
+ "embedding",
2458
+ updates.embedding ? JSON.stringify(updates.embedding) : null
2459
+ );
2460
+ }
2461
+ if (updates.embeddingModel !== void 0) {
2462
+ mem._setRaw("embedding_model", updates.embeddingModel || null);
2463
+ }
2464
+ });
2465
+ return memory;
2466
+ });
2467
+ return { ok: true, memory: memoryToStored(updated) };
2468
+ } catch (err) {
2469
+ return {
2470
+ ok: false,
2471
+ reason: "error",
2472
+ error: err instanceof Error ? err : new Error(String(err))
2473
+ };
2474
+ }
2475
+ }
2476
+ async function deleteMemoryByIdOp(ctx, id) {
2477
+ try {
2478
+ const memory = await ctx.memoriesCollection.find(id);
2479
+ await ctx.database.write(async () => {
2480
+ await memory.update((mem) => {
2481
+ mem._setRaw("is_deleted", true);
2482
+ });
2483
+ });
2484
+ } catch {
2485
+ }
2486
+ }
2487
+ async function deleteMemoryOp(ctx, namespace, key, value) {
2488
+ const uniqueKey = generateUniqueKey(namespace, key, value);
2489
+ const results = await ctx.memoriesCollection.query(Q2.where("unique_key", uniqueKey)).fetch();
2490
+ if (results.length > 0) {
2491
+ await ctx.database.write(async () => {
2492
+ await results[0].update((mem) => {
2493
+ mem._setRaw("is_deleted", true);
2494
+ });
2495
+ });
2496
+ }
2497
+ }
2498
+ async function deleteMemoriesByKeyOp(ctx, namespace, key) {
2499
+ const compositeKey = generateCompositeKey(namespace, key);
2500
+ const results = await ctx.memoriesCollection.query(Q2.where("composite_key", compositeKey), Q2.where("is_deleted", false)).fetch();
2501
+ await ctx.database.write(async () => {
2502
+ for (const memory of results) {
2503
+ await memory.update((mem) => {
2504
+ mem._setRaw("is_deleted", true);
2505
+ });
2506
+ }
2507
+ });
2508
+ }
2509
+ async function clearAllMemoriesOp(ctx) {
2510
+ const results = await ctx.memoriesCollection.query(Q2.where("is_deleted", false)).fetch();
2511
+ await ctx.database.write(async () => {
2512
+ for (const memory of results) {
2513
+ await memory.update((mem) => {
2514
+ mem._setRaw("is_deleted", true);
2515
+ });
2516
+ }
2517
+ });
2518
+ }
2519
+ async function searchSimilarMemoriesOp(ctx, queryEmbedding, limit = 10, minSimilarity = 0.6) {
2520
+ const allMemories = await ctx.memoriesCollection.query(Q2.where("is_deleted", false)).fetch();
2521
+ const memoriesWithEmbeddings = allMemories.filter(
2522
+ (m) => m.embedding && m.embedding.length > 0
2523
+ );
2524
+ if (memoriesWithEmbeddings.length === 0) {
2525
+ return [];
2526
+ }
2527
+ const results = memoriesWithEmbeddings.map((memory) => {
2528
+ const similarity = cosineSimilarity(queryEmbedding, memory.embedding);
2529
+ return {
2530
+ ...memoryToStored(memory),
2531
+ similarity
2532
+ };
2533
+ }).filter((result) => result.similarity >= minSimilarity).sort((a, b) => b.similarity - a.similarity).slice(0, limit);
2534
+ return results;
2535
+ }
2536
+ async function updateMemoryEmbeddingOp(ctx, id, embedding, embeddingModel) {
2537
+ try {
2538
+ const memory = await ctx.memoriesCollection.find(id);
2539
+ await ctx.database.write(async () => {
2540
+ await memory.update((mem) => {
2541
+ mem._setRaw("embedding", JSON.stringify(embedding));
2542
+ mem._setRaw("embedding_model", embeddingModel);
2543
+ });
2544
+ });
2545
+ } catch {
2546
+ }
2547
+ }
2548
+
2549
+ // src/lib/memory/service.ts
2550
+ var FACT_EXTRACTION_PROMPT = `You are a memory extraction system. Extract durable user memories from chat messages.
2551
+
2552
+ CRITICAL: You MUST respond with ONLY valid JSON. No explanations, no markdown, no code blocks, just pure JSON.
2553
+
2554
+ Only store clear, factual statements that might be relevant for future context or reference. Extract facts that will be useful in future conversations, such as identity, stable preferences, ongoing projects, skills, locations, favorites, and constraints.
2555
+
2556
+ Do not extract sensitive attributes, temporary things, or single-use instructions.
2557
+
2558
+ You must also extract stable personal preferences, including food likes/dislikes, hobbies, favorite items, favorite genres, or other enduring tastes.
2559
+
2560
+ If there are no memories to extract, return: {"items": []}
2561
+
2562
+ Response format (JSON only, no other text):
2563
+
2564
+ {
2565
+ "items": [
2566
+ {
2567
+ "type": "identity",
2568
+ "namespace": "identity",
2569
+ "key": "name",
2570
+ "value": "Charlie",
2571
+ "rawEvidence": "I'm Charlie",
2572
+ "confidence": 0.98,
2573
+ "pii": true
2574
+ },
2575
+ {
2576
+ "type": "identity",
2577
+ "namespace": "work",
2578
+ "key": "company",
2579
+ "value": "ZetaChain",
2580
+ "rawEvidence": "called ZetaChain",
2581
+ "confidence": 0.99,
2582
+ "pii": false
2583
+ },
2584
+ {
2585
+ "type": "identity",
2586
+ "namespace": "location",
2587
+ "key": "city",
2588
+ "value": "San Francisco",
2589
+ "rawEvidence": "I live in San Francisco",
2590
+ "confidence": 0.99,
2591
+ "pii": false
2592
+ },
2593
+ {
2594
+ "type": "preference",
2595
+ "namespace": "location",
2596
+ "key": "country",
2597
+ "value": "Japan",
2598
+ "rawEvidence": "I like to travel to the Japan",
2599
+ "confidence": 0.94,
2600
+ "pii": false
2601
+ },
2602
+ {
2603
+ "type": "preference",
2604
+ "namespace": "answer_style",
2605
+ "key": "verbosity",
2606
+ "value": "concise_direct",
2607
+ "rawEvidence": "I prefer concise, direct answers",
2608
+ "confidence": 0.96,
2609
+ "pii": false
2610
+ },
2611
+ {
2612
+ "type": "identity",
2613
+ "namespace": "timezone",
2614
+ "key": "tz",
2615
+ "value": "America/Los_Angeles",
2616
+ "rawEvidence": "I'm in PST",
2617
+ "confidence": 0.9,
2618
+ "pii": false
2619
+ },
2620
+ {
2621
+ "type": "preference",
2622
+ "namespace": "food",
2623
+ "key": "likes_ice_cream",
2624
+ "value": "ice cream",
2625
+ "rawEvidence": "I like ice cream",
2626
+ "confidence": 0.95,
2627
+ "pii": false
2628
+ }
2629
+ ]
2630
+ }`;
2631
+ var preprocessMemories = (items, minConfidence = 0.6) => {
2632
+ if (!items || !Array.isArray(items)) {
2633
+ return [];
2634
+ }
2635
+ const validItems = items.filter((item) => {
2636
+ if (item.namespace == null || item.key == null || item.value == null) {
2637
+ console.warn(
2638
+ "Dropping memory item with null/undefined namespace, key, or value:",
2639
+ item
2640
+ );
2641
+ return false;
2642
+ }
2643
+ const namespace = String(item.namespace).trim();
2644
+ const key = String(item.key).trim();
2645
+ const value = String(item.value).trim();
2646
+ if (namespace === "" || key === "" || value === "") {
2647
+ console.warn(
2648
+ "Dropping memory item with empty namespace, key, or value after trimming:",
2649
+ item
2650
+ );
2651
+ return false;
2652
+ }
2653
+ if (typeof item.confidence !== "number" || item.confidence < minConfidence) {
2654
+ console.warn(
2655
+ `Dropping memory item with confidence ${item.confidence} below threshold ${minConfidence}:`,
2656
+ item
2657
+ );
2658
+ return false;
2659
+ }
2660
+ return true;
2661
+ });
2662
+ const deduplicatedMap = /* @__PURE__ */ new Map();
2663
+ for (const item of validItems) {
2664
+ const uniqueKey = `${item.namespace}:${item.key}:${item.value}`;
2665
+ const existing = deduplicatedMap.get(uniqueKey);
2666
+ if (!existing || item.confidence > existing.confidence) {
2667
+ deduplicatedMap.set(uniqueKey, item);
2668
+ } else {
2669
+ console.debug(
2670
+ `Deduplicating memory item: keeping entry with higher confidence (${existing.confidence} > ${item.confidence})`,
2671
+ { namespace: item.namespace, key: item.key, value: item.value }
2672
+ );
2673
+ }
2674
+ }
2675
+ return Array.from(deduplicatedMap.values());
2676
+ };
2677
+
2678
+ // src/lib/memory/constants.ts
2679
+ var DEFAULT_API_EMBEDDING_MODEL = "openai/text-embedding-3-small";
2680
+ var DEFAULT_COMPLETION_MODEL = "openai/gpt-4o";
2681
+
2682
+ // src/expo/useMemoryStorage.ts
2683
+ import { postApiV1Embeddings } from "@reverbia/sdk";
2684
+ async function generateEmbeddingForTextApi(text4, options) {
2685
+ const token = options.getToken ? await options.getToken() : null;
2686
+ if (!token) {
2687
+ throw new Error("No auth token available for embedding generation");
2688
+ }
2689
+ const response = await postApiV1Embeddings({
2690
+ baseUrl: options.baseUrl,
2691
+ body: {
2692
+ input: text4,
2693
+ model: options.model
2694
+ },
2695
+ headers: {
2696
+ Authorization: `Bearer ${token}`
2697
+ }
2698
+ });
2699
+ if (!response.data || typeof response.data === "string") {
2700
+ throw new Error("Failed to generate embedding");
2701
+ }
2702
+ const embedding = response.data.data?.[0]?.embedding;
2703
+ if (!embedding) {
2704
+ throw new Error("No embedding in response");
2705
+ }
2706
+ return embedding;
2707
+ }
2708
+ async function generateEmbeddingForMemoryApi(memory, options) {
2709
+ const text4 = `${memory.type}: ${memory.namespace}/${memory.key} = ${memory.value}. Evidence: ${memory.rawEvidence}`;
2710
+ return generateEmbeddingForTextApi(text4, options);
2711
+ }
2712
+ function useMemoryStorage(options) {
2713
+ const {
2714
+ database,
2715
+ completionsModel = DEFAULT_COMPLETION_MODEL,
2716
+ embeddingModel: userEmbeddingModel,
2717
+ generateEmbeddings = true,
2718
+ onFactsExtracted,
2719
+ getToken,
2720
+ baseUrl = BASE_URL
2721
+ } = options;
2722
+ const embeddingModel = userEmbeddingModel === void 0 ? DEFAULT_API_EMBEDDING_MODEL : userEmbeddingModel;
2723
+ const [memories, setMemories] = useState5([]);
2724
+ const extractionInProgressRef = useRef4(false);
2725
+ const memoriesCollection = useMemo2(
2726
+ () => database.get("memories"),
2727
+ [database]
2728
+ );
2729
+ const storageCtx = useMemo2(
2730
+ () => ({
2731
+ database,
2732
+ memoriesCollection
2733
+ }),
2734
+ [database, memoriesCollection]
2735
+ );
2736
+ const embeddingOptions = useMemo2(
2737
+ () => ({
2738
+ model: embeddingModel ?? DEFAULT_API_EMBEDDING_MODEL,
2739
+ getToken: getToken || void 0,
2740
+ baseUrl
2741
+ }),
2742
+ [embeddingModel, getToken, baseUrl]
2743
+ );
2744
+ const refreshMemories = useCallback5(async () => {
2745
+ const storedMemories = await getAllMemoriesOp(storageCtx);
2746
+ setMemories(storedMemories);
2747
+ }, [storageCtx]);
2748
+ const extractMemoriesFromMessage = useCallback5(
2749
+ async (opts) => {
2750
+ const { messages, model } = opts;
2751
+ if (!getToken || extractionInProgressRef.current) {
2752
+ return null;
2753
+ }
2754
+ extractionInProgressRef.current = true;
2755
+ try {
2756
+ const token = await getToken();
2757
+ if (!token) {
2758
+ console.error("No access token available for memory extraction");
2759
+ return null;
2760
+ }
2761
+ const completion = await postApiV1ChatCompletions({
2762
+ baseUrl,
2763
+ body: {
2764
+ messages: [
2765
+ {
2766
+ role: "system",
2767
+ content: [{ type: "text", text: FACT_EXTRACTION_PROMPT }]
2768
+ },
2769
+ ...messages.map((m) => ({
2770
+ role: m.role,
2771
+ content: [{ type: "text", text: m.content }]
2772
+ }))
2773
+ ],
2774
+ model: model || completionsModel
2775
+ },
2776
+ headers: {
2777
+ Authorization: `Bearer ${token}`
2778
+ }
2779
+ });
2780
+ if (!completion.data) {
2781
+ console.error(
2782
+ "Memory extraction failed:",
2783
+ completion.error?.error ?? "API did not return a response"
2784
+ );
2785
+ return null;
2786
+ }
2787
+ if (typeof completion.data === "string") {
2788
+ console.error(
2789
+ "Memory extraction failed: API returned a string response"
2790
+ );
2791
+ return null;
2792
+ }
2793
+ const messageContent = completion.data.choices?.[0]?.message?.content;
2794
+ let content = "";
2795
+ if (Array.isArray(messageContent)) {
2796
+ content = messageContent.map((p) => p.text || "").join("").trim();
2797
+ } else if (typeof messageContent === "string") {
2798
+ content = messageContent.trim();
2799
+ }
2800
+ if (!content) {
2801
+ console.error("No content in memory extraction response");
2802
+ return null;
2803
+ }
2804
+ let jsonContent = content;
2805
+ jsonContent = jsonContent.replace(/^data:\s*/gm, "").trim();
2806
+ if (jsonContent.startsWith("{")) {
2807
+ let braceCount = 0;
2808
+ let jsonStart = -1;
2809
+ let jsonEnd = -1;
2810
+ for (let i = 0; i < jsonContent.length; i++) {
2811
+ if (jsonContent[i] === "{") {
2812
+ if (jsonStart === -1) jsonStart = i;
2813
+ braceCount++;
2814
+ } else if (jsonContent[i] === "}") {
2815
+ braceCount--;
2816
+ if (braceCount === 0 && jsonStart !== -1) {
2817
+ jsonEnd = i + 1;
2818
+ break;
2819
+ }
2820
+ }
2821
+ }
2822
+ if (jsonStart !== -1 && jsonEnd !== -1) {
2823
+ jsonContent = jsonContent.substring(jsonStart, jsonEnd);
2824
+ }
2825
+ } else {
2826
+ const jsonMatch = jsonContent.match(
2827
+ /```(?:json)?\s*(\{[\s\S]*?\})\s*```/
2828
+ );
2829
+ if (jsonMatch && jsonMatch[1]) {
2830
+ jsonContent = jsonMatch[1].trim();
2831
+ } else {
2832
+ const jsonObjectMatch = jsonContent.match(/\{[\s\S]*\}/);
2833
+ if (jsonObjectMatch && jsonObjectMatch[0]) {
2834
+ jsonContent = jsonObjectMatch[0];
2835
+ } else {
2836
+ console.warn("Memory extraction returned non-JSON response.");
2837
+ return { items: [] };
2838
+ }
2839
+ }
2840
+ }
2841
+ const trimmedJson = jsonContent.trim();
2842
+ if (!trimmedJson.startsWith("{") || !trimmedJson.includes("items")) {
2843
+ console.warn("Memory extraction response doesn't appear to be valid JSON.");
2844
+ return { items: [] };
2845
+ }
2846
+ let result;
2847
+ try {
2848
+ result = JSON.parse(jsonContent);
2849
+ if (!result || typeof result !== "object") {
2850
+ throw new Error("Invalid JSON structure: not an object");
2851
+ }
2852
+ if (!Array.isArray(result.items)) {
2853
+ console.warn("Memory extraction result missing 'items' array.");
2854
+ return { items: [] };
2855
+ }
2856
+ } catch (parseError) {
2857
+ console.error(
2858
+ "Failed to parse memory extraction JSON:",
2859
+ parseError instanceof Error ? parseError.message : "Unknown error"
2860
+ );
2861
+ return { items: [] };
2862
+ }
2863
+ if (result.items && Array.isArray(result.items)) {
2864
+ result.items = preprocessMemories(result.items);
2865
+ }
2866
+ if (result.items && result.items.length > 0) {
2867
+ try {
2868
+ const createOptions = result.items.map(
2869
+ (item) => ({
2870
+ type: item.type,
2871
+ namespace: item.namespace,
2872
+ key: item.key,
2873
+ value: item.value,
2874
+ rawEvidence: item.rawEvidence,
2875
+ confidence: item.confidence,
2876
+ pii: item.pii
2877
+ })
2878
+ );
2879
+ const savedMemories = await saveMemoriesOp(storageCtx, createOptions);
2880
+ console.log(`Saved ${savedMemories.length} memories to WatermelonDB`);
2881
+ if (generateEmbeddings && embeddingModel) {
2882
+ try {
2883
+ for (const saved of savedMemories) {
2884
+ const memoryItem = {
2885
+ type: saved.type,
2886
+ namespace: saved.namespace,
2887
+ key: saved.key,
2888
+ value: saved.value,
2889
+ rawEvidence: saved.rawEvidence,
2890
+ confidence: saved.confidence,
2891
+ pii: saved.pii
2892
+ };
2893
+ const embedding = await generateEmbeddingForMemoryApi(
2894
+ memoryItem,
2895
+ embeddingOptions
2896
+ );
2897
+ await updateMemoryEmbeddingOp(
2898
+ storageCtx,
2899
+ saved.uniqueId,
2900
+ embedding,
2901
+ embeddingOptions.model
2902
+ );
2903
+ }
2904
+ console.log(`Generated embeddings for ${savedMemories.length} memories`);
2905
+ } catch (error) {
2906
+ console.error("Failed to generate embeddings:", error);
2907
+ }
2908
+ }
2909
+ await refreshMemories();
2910
+ } catch (error) {
2911
+ console.error("Failed to save memories to WatermelonDB:", error);
2912
+ }
2913
+ }
2914
+ if (onFactsExtracted) {
2915
+ onFactsExtracted(result);
2916
+ }
2917
+ return result;
2918
+ } catch (error) {
2919
+ console.error("Failed to extract facts:", error);
2920
+ return null;
2921
+ } finally {
2922
+ extractionInProgressRef.current = false;
2923
+ }
2924
+ },
2925
+ [
2926
+ completionsModel,
2927
+ embeddingModel,
2928
+ embeddingOptions,
2929
+ generateEmbeddings,
2930
+ getToken,
2931
+ onFactsExtracted,
2932
+ baseUrl,
2933
+ storageCtx,
2934
+ refreshMemories
2935
+ ]
2936
+ );
2937
+ const searchMemories = useCallback5(
2938
+ async (query, limit = 10, minSimilarity = 0.6) => {
2939
+ if (!embeddingModel) {
2940
+ console.warn("Cannot search memories: embeddingModel not provided");
2941
+ return [];
2942
+ }
2943
+ try {
2944
+ const queryEmbedding = await generateEmbeddingForTextApi(
2945
+ query,
2946
+ embeddingOptions
2947
+ );
2948
+ const results = await searchSimilarMemoriesOp(
2949
+ storageCtx,
2950
+ queryEmbedding,
2951
+ limit,
2952
+ minSimilarity
2953
+ );
2954
+ if (results.length === 0) {
2955
+ console.warn(
2956
+ `[Memory Search] No memories found above similarity threshold ${minSimilarity}.`
2957
+ );
2958
+ } else {
2959
+ console.log(
2960
+ `[Memory Search] Found ${results.length} memories. Similarity scores: ${results.map((r) => r.similarity.toFixed(3)).join(", ")}`
2961
+ );
2962
+ }
2963
+ return results;
2964
+ } catch {
2965
+ return [];
2966
+ }
2967
+ },
2968
+ [embeddingModel, embeddingOptions, storageCtx]
2969
+ );
2970
+ const fetchAllMemories = useCallback5(async () => {
2971
+ try {
2972
+ return await getAllMemoriesOp(storageCtx);
2973
+ } catch (error) {
2974
+ throw new Error(
2975
+ "Failed to fetch all memories: " + (error instanceof Error ? error.message : String(error))
2976
+ );
2977
+ }
2978
+ }, [storageCtx]);
2979
+ const fetchMemoriesByNamespace = useCallback5(
2980
+ async (namespace) => {
2981
+ if (!namespace) {
2982
+ throw new Error("Missing required field: namespace");
2983
+ }
2984
+ try {
2985
+ return await getMemoriesByNamespaceOp(storageCtx, namespace);
2986
+ } catch (error) {
2987
+ throw new Error(
2988
+ `Failed to fetch memories for namespace "${namespace}": ` + (error instanceof Error ? error.message : String(error))
2989
+ );
2990
+ }
2991
+ },
2992
+ [storageCtx]
2993
+ );
2994
+ const fetchMemoriesByKey = useCallback5(
2995
+ async (namespace, key) => {
2996
+ if (!namespace || !key) {
2997
+ throw new Error("Missing required fields: namespace, key");
2998
+ }
2999
+ try {
3000
+ return await getMemoriesByKeyOp(storageCtx, namespace, key);
3001
+ } catch (error) {
3002
+ throw new Error(
3003
+ `Failed to fetch memories for "${namespace}:${key}": ` + (error instanceof Error ? error.message : String(error))
3004
+ );
3005
+ }
3006
+ },
3007
+ [storageCtx]
3008
+ );
3009
+ const getMemoryById = useCallback5(
3010
+ async (id) => {
3011
+ try {
3012
+ return await getMemoryByIdOp(storageCtx, id);
3013
+ } catch (error) {
3014
+ throw new Error(
3015
+ `Failed to get memory ${id}: ` + (error instanceof Error ? error.message : String(error))
3016
+ );
3017
+ }
3018
+ },
3019
+ [storageCtx]
3020
+ );
3021
+ const saveMemory = useCallback5(
3022
+ async (memory) => {
3023
+ try {
3024
+ const saved = await saveMemoryOp(storageCtx, memory);
3025
+ if (generateEmbeddings && embeddingModel && !memory.embedding) {
3026
+ try {
3027
+ const memoryItem = {
3028
+ type: memory.type,
3029
+ namespace: memory.namespace,
3030
+ key: memory.key,
3031
+ value: memory.value,
3032
+ rawEvidence: memory.rawEvidence,
3033
+ confidence: memory.confidence,
3034
+ pii: memory.pii
3035
+ };
3036
+ const embedding = await generateEmbeddingForMemoryApi(
3037
+ memoryItem,
3038
+ embeddingOptions
3039
+ );
3040
+ await updateMemoryEmbeddingOp(
3041
+ storageCtx,
3042
+ saved.uniqueId,
3043
+ embedding,
3044
+ embeddingOptions.model
3045
+ );
3046
+ } catch (error) {
3047
+ console.error("Failed to generate embedding:", error);
3048
+ }
3049
+ }
3050
+ setMemories((prev) => {
3051
+ const existing = prev.find((m) => m.uniqueId === saved.uniqueId);
3052
+ if (existing) {
3053
+ return prev.map((m) => m.uniqueId === saved.uniqueId ? saved : m);
3054
+ }
3055
+ return [saved, ...prev];
3056
+ });
3057
+ return saved;
3058
+ } catch (error) {
3059
+ throw new Error(
3060
+ "Failed to save memory: " + (error instanceof Error ? error.message : String(error))
3061
+ );
3062
+ }
3063
+ },
3064
+ [storageCtx, generateEmbeddings, embeddingModel, embeddingOptions]
3065
+ );
3066
+ const saveMemories = useCallback5(
3067
+ async (memoriesToSave) => {
3068
+ try {
3069
+ const saved = await saveMemoriesOp(storageCtx, memoriesToSave);
3070
+ if (generateEmbeddings && embeddingModel) {
3071
+ for (let i = 0; i < saved.length; i++) {
3072
+ const memory = memoriesToSave[i];
3073
+ if (!memory.embedding) {
3074
+ try {
3075
+ const memoryItem = {
3076
+ type: memory.type,
3077
+ namespace: memory.namespace,
3078
+ key: memory.key,
3079
+ value: memory.value,
3080
+ rawEvidence: memory.rawEvidence,
3081
+ confidence: memory.confidence,
3082
+ pii: memory.pii
3083
+ };
3084
+ const embedding = await generateEmbeddingForMemoryApi(
3085
+ memoryItem,
3086
+ embeddingOptions
3087
+ );
3088
+ await updateMemoryEmbeddingOp(
3089
+ storageCtx,
3090
+ saved[i].uniqueId,
3091
+ embedding,
3092
+ embeddingOptions.model
3093
+ );
3094
+ } catch (error) {
3095
+ console.error("Failed to generate embedding:", error);
3096
+ }
3097
+ }
3098
+ }
3099
+ }
3100
+ await refreshMemories();
3101
+ return saved;
3102
+ } catch (error) {
3103
+ throw new Error(
3104
+ "Failed to save memories: " + (error instanceof Error ? error.message : String(error))
3105
+ );
3106
+ }
3107
+ },
3108
+ [storageCtx, generateEmbeddings, embeddingModel, embeddingOptions, refreshMemories]
3109
+ );
3110
+ const updateMemory = useCallback5(
3111
+ async (id, updates) => {
3112
+ const result = await updateMemoryOp(storageCtx, id, updates);
3113
+ if (!result.ok) {
3114
+ if (result.reason === "not_found") {
3115
+ return null;
3116
+ }
3117
+ if (result.reason === "conflict") {
3118
+ throw new Error(
3119
+ `Cannot update memory: a memory with key "${result.conflictingKey}" already exists`
3120
+ );
3121
+ }
3122
+ throw new Error(
3123
+ `Failed to update memory ${id}: ${result.error.message}`
3124
+ );
3125
+ }
3126
+ const updated = result.memory;
3127
+ const contentChanged = updates.value !== void 0 || updates.rawEvidence !== void 0 || updates.type !== void 0 || updates.namespace !== void 0 || updates.key !== void 0;
3128
+ if (contentChanged && generateEmbeddings && embeddingModel && !updates.embedding) {
3129
+ try {
3130
+ const memoryItem = {
3131
+ type: updated.type,
3132
+ namespace: updated.namespace,
3133
+ key: updated.key,
3134
+ value: updated.value,
3135
+ rawEvidence: updated.rawEvidence,
3136
+ confidence: updated.confidence,
3137
+ pii: updated.pii
3138
+ };
3139
+ const embedding = await generateEmbeddingForMemoryApi(
3140
+ memoryItem,
3141
+ embeddingOptions
3142
+ );
3143
+ await updateMemoryEmbeddingOp(storageCtx, id, embedding, embeddingOptions.model);
3144
+ } catch (error) {
3145
+ console.error("Failed to regenerate embedding:", error);
3146
+ }
3147
+ }
3148
+ setMemories((prev) => prev.map((m) => m.uniqueId === id ? updated : m));
3149
+ return updated;
3150
+ },
3151
+ [storageCtx, generateEmbeddings, embeddingModel, embeddingOptions]
3152
+ );
3153
+ const removeMemory = useCallback5(
3154
+ async (namespace, key, value) => {
3155
+ if (!namespace || !key || !value) {
3156
+ throw new Error("Missing required fields: namespace, key, value");
3157
+ }
3158
+ try {
3159
+ await deleteMemoryOp(storageCtx, namespace, key, value);
3160
+ setMemories(
3161
+ (prev) => prev.filter(
3162
+ (m) => !(m.namespace === namespace && m.key === key && m.value === value)
3163
+ )
3164
+ );
3165
+ } catch (error) {
3166
+ throw new Error(
3167
+ `Failed to delete memory "${namespace}:${key}:${value}": ` + (error instanceof Error ? error.message : String(error))
3168
+ );
3169
+ }
3170
+ },
3171
+ [storageCtx]
3172
+ );
3173
+ const removeMemoryById = useCallback5(
3174
+ async (id) => {
3175
+ try {
3176
+ await deleteMemoryByIdOp(storageCtx, id);
3177
+ setMemories((prev) => prev.filter((m) => m.uniqueId !== id));
3178
+ } catch (error) {
3179
+ throw new Error(
3180
+ `Failed to delete memory with id ${id}: ` + (error instanceof Error ? error.message : String(error))
3181
+ );
3182
+ }
3183
+ },
3184
+ [storageCtx]
3185
+ );
3186
+ const removeMemories = useCallback5(
3187
+ async (namespace, key) => {
3188
+ if (!namespace || !key) {
3189
+ throw new Error("Missing required fields: namespace, key");
3190
+ }
3191
+ try {
3192
+ await deleteMemoriesByKeyOp(storageCtx, namespace, key);
3193
+ setMemories(
3194
+ (prev) => prev.filter((m) => !(m.namespace === namespace && m.key === key))
3195
+ );
3196
+ } catch (error) {
3197
+ throw new Error(
3198
+ `Failed to delete memories for "${namespace}:${key}": ` + (error instanceof Error ? error.message : String(error))
3199
+ );
3200
+ }
3201
+ },
3202
+ [storageCtx]
3203
+ );
3204
+ const clearMemories = useCallback5(async () => {
3205
+ try {
3206
+ await clearAllMemoriesOp(storageCtx);
3207
+ setMemories([]);
3208
+ } catch (error) {
3209
+ throw new Error(
3210
+ "Failed to clear all memories: " + (error instanceof Error ? error.message : String(error))
3211
+ );
3212
+ }
3213
+ }, [storageCtx]);
3214
+ return {
3215
+ memories,
3216
+ refreshMemories,
3217
+ extractMemoriesFromMessage,
3218
+ searchMemories,
3219
+ fetchAllMemories,
3220
+ fetchMemoriesByNamespace,
3221
+ fetchMemoriesByKey,
3222
+ getMemoryById,
3223
+ saveMemory,
3224
+ saveMemories,
3225
+ updateMemory,
3226
+ removeMemory,
3227
+ removeMemoryById,
3228
+ removeMemories,
3229
+ clearMemories
3230
+ };
3231
+ }
3232
+
3233
+ // src/lib/db/schema.ts
3234
+ import { appSchema as appSchema3, tableSchema as tableSchema3 } from "@nozbe/watermelondb";
3235
+ import {
3236
+ schemaMigrations as schemaMigrations2,
3237
+ addColumns as addColumns2,
3238
+ createTable
3239
+ } from "@nozbe/watermelondb/Schema/migrations";
3240
+
3241
+ // src/lib/db/settings/models.ts
3242
+ import { Model as Model3 } from "@nozbe/watermelondb";
3243
+ import { text as text3 } from "@nozbe/watermelondb/decorators";
3244
+ var ModelPreference = class extends Model3 {
3245
+ };
3246
+ ModelPreference.table = "modelPreferences";
3247
+ __decorateClass([
3248
+ text3("wallet_address")
3249
+ ], ModelPreference.prototype, "walletAddress", 2);
3250
+ __decorateClass([
3251
+ text3("models")
3252
+ ], ModelPreference.prototype, "models", 2);
3253
+
3254
+ // src/lib/db/schema.ts
3255
+ var SDK_SCHEMA_VERSION = 6;
3256
+ var sdkSchema = appSchema3({
3257
+ version: SDK_SCHEMA_VERSION,
3258
+ tables: [
3259
+ // Chat storage tables
3260
+ tableSchema3({
3261
+ name: "history",
3262
+ columns: [
3263
+ { name: "message_id", type: "number" },
3264
+ { name: "conversation_id", type: "string", isIndexed: true },
3265
+ { name: "role", type: "string", isIndexed: true },
3266
+ { name: "content", type: "string" },
3267
+ { name: "model", type: "string", isOptional: true },
3268
+ { name: "files", type: "string", isOptional: true },
3269
+ { name: "created_at", type: "number", isIndexed: true },
3270
+ { name: "updated_at", type: "number" },
3271
+ { name: "vector", type: "string", isOptional: true },
3272
+ { name: "embedding_model", type: "string", isOptional: true },
3273
+ { name: "usage", type: "string", isOptional: true },
3274
+ { name: "sources", type: "string", isOptional: true },
3275
+ { name: "response_duration", type: "number", isOptional: true },
3276
+ { name: "was_stopped", type: "boolean", isOptional: true },
3277
+ { name: "error", type: "string", isOptional: true },
3278
+ { name: "thought_process", type: "string", isOptional: true }
3279
+ // JSON stringified ActivityPhase[]
3280
+ ]
3281
+ }),
3282
+ tableSchema3({
3283
+ name: "conversations",
3284
+ columns: [
3285
+ { name: "conversation_id", type: "string", isIndexed: true },
3286
+ { name: "title", type: "string" },
3287
+ { name: "created_at", type: "number" },
3288
+ { name: "updated_at", type: "number" },
3289
+ { name: "is_deleted", type: "boolean", isIndexed: true }
3290
+ ]
3291
+ }),
3292
+ // Memory storage tables
3293
+ tableSchema3({
3294
+ name: "memories",
3295
+ columns: [
3296
+ { name: "type", type: "string", isIndexed: true },
3297
+ { name: "namespace", type: "string", isIndexed: true },
3298
+ { name: "key", type: "string", isIndexed: true },
3299
+ { name: "value", type: "string" },
3300
+ { name: "raw_evidence", type: "string" },
3301
+ { name: "confidence", type: "number" },
3302
+ { name: "pii", type: "boolean", isIndexed: true },
3303
+ { name: "composite_key", type: "string", isIndexed: true },
3304
+ { name: "unique_key", type: "string", isIndexed: true },
3305
+ { name: "created_at", type: "number", isIndexed: true },
3306
+ { name: "updated_at", type: "number" },
3307
+ { name: "embedding", type: "string", isOptional: true },
3308
+ { name: "embedding_model", type: "string", isOptional: true },
3309
+ { name: "is_deleted", type: "boolean", isIndexed: true }
3310
+ ]
3311
+ }),
3312
+ // Settings storage tables
3313
+ tableSchema3({
3314
+ name: "modelPreferences",
3315
+ columns: [
3316
+ { name: "wallet_address", type: "string", isIndexed: true },
3317
+ { name: "models", type: "string", isOptional: true }
3318
+ ]
3319
+ })
3320
+ ]
3321
+ });
3322
+ var sdkMigrations = schemaMigrations2({
3323
+ migrations: [
3324
+ // v2 -> v3: Added was_stopped column to history
3325
+ {
3326
+ toVersion: 3,
3327
+ steps: [
3328
+ addColumns2({
3329
+ table: "history",
3330
+ columns: [{ name: "was_stopped", type: "boolean", isOptional: true }]
3331
+ })
3332
+ ]
3333
+ },
3334
+ // v3 -> v4: Added settings storage (modelPreferences table)
3335
+ {
3336
+ toVersion: 4,
3337
+ steps: [
3338
+ createTable({
3339
+ name: "modelPreferences",
3340
+ columns: [
3341
+ { name: "wallet_address", type: "string", isIndexed: true },
3342
+ { name: "models", type: "string", isOptional: true }
3343
+ ]
3344
+ })
3345
+ ]
3346
+ },
3347
+ // v4 -> v5: Added error column to history for error persistence
3348
+ {
3349
+ toVersion: 5,
3350
+ steps: [
3351
+ addColumns2({
3352
+ table: "history",
3353
+ columns: [{ name: "error", type: "string", isOptional: true }]
3354
+ })
3355
+ ]
3356
+ },
3357
+ // v5 -> v6: Added thought_process column to history table
3358
+ {
3359
+ toVersion: 6,
3360
+ steps: [
3361
+ addColumns2({
3362
+ table: "history",
3363
+ columns: [
3364
+ { name: "thought_process", type: "string", isOptional: true }
3365
+ ]
3366
+ })
3367
+ ]
3368
+ }
3369
+ ]
3370
+ });
3371
+ var sdkModelClasses = [
3372
+ Message,
3373
+ Conversation,
3374
+ Memory,
3375
+ ModelPreference
3376
+ ];
3377
+ export {
3378
+ Conversation as ChatConversation,
3379
+ Message as ChatMessage,
3380
+ Memory as StoredMemoryModel,
3381
+ chatStorageMigrations,
3382
+ chatStorageSchema,
3383
+ generateCompositeKey,
3384
+ generateConversationId,
3385
+ generateUniqueKey,
3386
+ memoryStorageSchema,
3387
+ sdkMigrations,
3388
+ sdkModelClasses,
3389
+ sdkSchema,
3390
+ useChat,
3391
+ useChatStorage,
3392
+ useImageGeneration,
3393
+ useMemoryStorage,
3394
+ useModels
3395
+ };