@reverbia/sdk 1.0.0-next.20251202085711 → 1.0.0-next.20251202092727

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.
@@ -177,7 +177,7 @@ type LlmapiRole = string;
177
177
 
178
178
  type SendMessageArgs = {
179
179
  messages: LlmapiMessage[];
180
- model: string;
180
+ model?: string;
181
181
  /**
182
182
  * Per-request callback for data chunks. Called in addition to the global
183
183
  * `onData` callback if provided in `useChat` options.
@@ -215,6 +215,17 @@ type UseChatOptions = {
215
215
  * @param error - The error that occurred (never an AbortError)
216
216
  */
217
217
  onError?: (error: Error) => void;
218
+ /**
219
+ * The provider to use for chat completions (default: "api")
220
+ * "local": Uses a local HuggingFace model (in-browser)
221
+ * "api": Uses the backend API
222
+ */
223
+ chatProvider?: "api" | "local";
224
+ /**
225
+ * The model to use for local chat completions
226
+ * Default is "ibm-granite/Granite-4.0-Nano-WebGPU"
227
+ */
228
+ localModel?: string;
218
229
  };
219
230
  type UseChatResult = {
220
231
  isLoading: boolean;
@@ -244,6 +255,8 @@ type UseChatResult = {
244
255
  * @param options.onFinish - Callback function to be called when the chat completion finishes successfully.
245
256
  * @param options.onError - Callback function to be called when an unexpected error
246
257
  * is encountered. Note: This is NOT called for aborted requests (see `stop()`).
258
+ * @param options.chatProvider - The provider to use for chat completions (default: "api").
259
+ * @param options.localModel - The model to use for local chat completions.
247
260
  *
248
261
  * @returns An object containing:
249
262
  * - `isLoading`: A boolean indicating whether a request is currently in progress
@@ -339,12 +352,20 @@ type UseMemoryOptions = {
339
352
  /**
340
353
  * The model to use for fact extraction (default: "openai/gpt-4o")
341
354
  */
342
- memoryModel?: string;
355
+ completionsModel?: string;
343
356
  /**
344
- * The model to use for generating embeddings (default: "openai/text-embedding-3-small")
345
- * Set to null/undefined to disable embedding generation
357
+ * The model to use for generating embeddings
358
+ * For local: default is "Snowflake/snowflake-arctic-embed-xs"
359
+ * For api: default is "openai/text-embedding-3-small"
360
+ * Set to null to disable embedding generation
346
361
  */
347
362
  embeddingModel?: string | null;
363
+ /**
364
+ * The provider to use for generating embeddings (default: "local")
365
+ * "local": Uses a local HuggingFace model (in-browser)
366
+ * "api": Uses the backend API
367
+ */
368
+ embeddingProvider?: "local" | "api";
348
369
  /**
349
370
  * Whether to automatically generate embeddings for extracted memories (default: true)
350
371
  */
@@ -177,7 +177,7 @@ type LlmapiRole = string;
177
177
 
178
178
  type SendMessageArgs = {
179
179
  messages: LlmapiMessage[];
180
- model: string;
180
+ model?: string;
181
181
  /**
182
182
  * Per-request callback for data chunks. Called in addition to the global
183
183
  * `onData` callback if provided in `useChat` options.
@@ -215,6 +215,17 @@ type UseChatOptions = {
215
215
  * @param error - The error that occurred (never an AbortError)
216
216
  */
217
217
  onError?: (error: Error) => void;
218
+ /**
219
+ * The provider to use for chat completions (default: "api")
220
+ * "local": Uses a local HuggingFace model (in-browser)
221
+ * "api": Uses the backend API
222
+ */
223
+ chatProvider?: "api" | "local";
224
+ /**
225
+ * The model to use for local chat completions
226
+ * Default is "ibm-granite/Granite-4.0-Nano-WebGPU"
227
+ */
228
+ localModel?: string;
218
229
  };
219
230
  type UseChatResult = {
220
231
  isLoading: boolean;
@@ -244,6 +255,8 @@ type UseChatResult = {
244
255
  * @param options.onFinish - Callback function to be called when the chat completion finishes successfully.
245
256
  * @param options.onError - Callback function to be called when an unexpected error
246
257
  * is encountered. Note: This is NOT called for aborted requests (see `stop()`).
258
+ * @param options.chatProvider - The provider to use for chat completions (default: "api").
259
+ * @param options.localModel - The model to use for local chat completions.
247
260
  *
248
261
  * @returns An object containing:
249
262
  * - `isLoading`: A boolean indicating whether a request is currently in progress
@@ -339,12 +352,20 @@ type UseMemoryOptions = {
339
352
  /**
340
353
  * The model to use for fact extraction (default: "openai/gpt-4o")
341
354
  */
342
- memoryModel?: string;
355
+ completionsModel?: string;
343
356
  /**
344
- * The model to use for generating embeddings (default: "openai/text-embedding-3-small")
345
- * Set to null/undefined to disable embedding generation
357
+ * The model to use for generating embeddings
358
+ * For local: default is "Snowflake/snowflake-arctic-embed-xs"
359
+ * For api: default is "openai/text-embedding-3-small"
360
+ * Set to null to disable embedding generation
346
361
  */
347
362
  embeddingModel?: string | null;
363
+ /**
364
+ * The provider to use for generating embeddings (default: "local")
365
+ * "local": Uses a local HuggingFace model (in-browser)
366
+ * "api": Uses the backend API
367
+ */
368
+ embeddingProvider?: "local" | "api";
348
369
  /**
349
370
  * Whether to automatically generate embeddings for extracted memories (default: true)
350
371
  */
@@ -1,3 +1,5 @@
1
+ import "./chunk-FBCDBTKJ.mjs";
2
+
1
3
  // src/react/useChat.ts
2
4
  import { useCallback, useEffect, useRef, useState } from "react";
3
5
 
@@ -816,6 +818,54 @@ var createClientConfig = (config) => ({
816
818
  // src/client/client.gen.ts
817
819
  var client = createClient(createClientConfig(createConfig()));
818
820
 
821
+ // src/lib/chat/constants.ts
822
+ var DEFAULT_LOCAL_CHAT_MODEL = "onnx-community/Qwen2.5-0.5B-Instruct";
823
+
824
+ // src/lib/chat/generation.ts
825
+ var chatPipeline = null;
826
+ var currentModel = null;
827
+ async function generateLocalChatCompletion(messages, options = {}) {
828
+ const {
829
+ model = DEFAULT_LOCAL_CHAT_MODEL,
830
+ temperature = 0.7,
831
+ max_tokens = 1024,
832
+ top_p = 0.9,
833
+ onToken,
834
+ signal
835
+ } = options;
836
+ const { pipeline, TextStreamer } = await import("./transformers.node-BSHUG7OY.mjs");
837
+ if (!chatPipeline || currentModel !== model) {
838
+ chatPipeline = await pipeline("text-generation", model, {
839
+ dtype: "fp16"
840
+ });
841
+ currentModel = model;
842
+ }
843
+ class CallbackStreamer extends TextStreamer {
844
+ constructor(tokenizer, cb) {
845
+ super(tokenizer, {
846
+ skip_prompt: true,
847
+ skip_special_tokens: true
848
+ });
849
+ this.cb = cb;
850
+ }
851
+ on_finalized_text(text) {
852
+ if (signal?.aborted) {
853
+ throw new Error("AbortError");
854
+ }
855
+ this.cb(text);
856
+ }
857
+ }
858
+ const streamer = onToken ? new CallbackStreamer(chatPipeline.tokenizer, onToken) : void 0;
859
+ const output = await chatPipeline(messages, {
860
+ max_new_tokens: max_tokens,
861
+ temperature,
862
+ top_p,
863
+ streamer,
864
+ return_full_text: false
865
+ });
866
+ return output;
867
+ }
868
+
819
869
  // src/react/useChat.ts
820
870
  function useChat(options) {
821
871
  const {
@@ -823,7 +873,9 @@ function useChat(options) {
823
873
  baseUrl = BASE_URL,
824
874
  onData: globalOnData,
825
875
  onFinish,
826
- onError
876
+ onError,
877
+ chatProvider = "api",
878
+ localModel = DEFAULT_LOCAL_CHAT_MODEL
827
879
  } = options || {};
828
880
  const [isLoading, setIsLoading] = useState(false);
829
881
  const abortControllerRef = useRef(null);
@@ -852,16 +904,6 @@ function useChat(options) {
852
904
  if (onError) onError(new Error(errorMsg));
853
905
  return { data: null, error: errorMsg };
854
906
  }
855
- if (!model) {
856
- const errorMsg = "model is required to call sendMessage.";
857
- if (onError) onError(new Error(errorMsg));
858
- return { data: null, error: errorMsg };
859
- }
860
- if (!getToken) {
861
- const errorMsg = "Token getter function is required.";
862
- if (onError) onError(new Error(errorMsg));
863
- return { data: null, error: errorMsg };
864
- }
865
907
  if (abortControllerRef.current) {
866
908
  abortControllerRef.current.abort();
867
909
  }
@@ -869,88 +911,141 @@ function useChat(options) {
869
911
  abortControllerRef.current = abortController;
870
912
  setIsLoading(true);
871
913
  try {
872
- const token = await getToken();
873
- if (!token) {
874
- const errorMsg = "No access token available.";
875
- setIsLoading(false);
876
- if (onError) onError(new Error(errorMsg));
877
- return { data: null, error: errorMsg };
878
- }
879
- const sseResult = await client.sse.post({
880
- baseUrl,
881
- url: "/api/v1/chat/completions",
882
- body: {
883
- messages,
884
- model,
885
- stream: true
886
- },
887
- headers: {
888
- "Content-Type": "application/json",
889
- Authorization: `Bearer ${token}`
890
- },
891
- signal: abortController.signal
892
- });
893
- let accumulatedContent = "";
894
- let completionId = "";
895
- let completionModel = "";
896
- let accumulatedUsage = {};
897
- let finishReason;
898
- for await (const chunk of sseResult.stream) {
899
- if (typeof chunk === "string" && (chunk.trim() === "[DONE]" || chunk.includes("[DONE]"))) {
900
- continue;
901
- }
902
- if (chunk && typeof chunk === "object") {
903
- const chunkData = chunk;
904
- if (chunkData.id && !completionId) {
905
- completionId = chunkData.id;
914
+ if (chatProvider === "local") {
915
+ let accumulatedContent = "";
916
+ const usedModel = localModel;
917
+ const formattedMessages = messages.map((m) => ({
918
+ role: m.role || "user",
919
+ content: m.content || ""
920
+ }));
921
+ await generateLocalChatCompletion(formattedMessages, {
922
+ model: usedModel,
923
+ signal: abortController.signal,
924
+ onToken: (token) => {
925
+ accumulatedContent += token;
926
+ if (onData) onData(token);
927
+ if (globalOnData) globalOnData(token);
906
928
  }
907
- if (chunkData.model && !completionModel) {
908
- completionModel = chunkData.model;
929
+ });
930
+ const completion = {
931
+ id: `local-${Date.now()}`,
932
+ model: usedModel,
933
+ choices: [
934
+ {
935
+ index: 0,
936
+ message: {
937
+ role: "assistant",
938
+ content: accumulatedContent
939
+ },
940
+ finish_reason: "stop"
941
+ }
942
+ ],
943
+ usage: {
944
+ prompt_tokens: 0,
945
+ // Not easily available from simple pipeline usage
946
+ completion_tokens: 0,
947
+ total_tokens: 0
909
948
  }
910
- if (chunkData.usage) {
911
- accumulatedUsage = {
912
- ...accumulatedUsage,
913
- ...chunkData.usage
914
- };
949
+ };
950
+ setIsLoading(false);
951
+ if (onFinish) {
952
+ onFinish(completion);
953
+ }
954
+ return { data: completion, error: null };
955
+ } else {
956
+ if (!model) {
957
+ const errorMsg = "model is required to call sendMessage.";
958
+ if (onError) onError(new Error(errorMsg));
959
+ return { data: null, error: errorMsg };
960
+ }
961
+ if (!getToken) {
962
+ const errorMsg = "Token getter function is required.";
963
+ if (onError) onError(new Error(errorMsg));
964
+ return { data: null, error: errorMsg };
965
+ }
966
+ const token = await getToken();
967
+ if (!token) {
968
+ const errorMsg = "No access token available.";
969
+ setIsLoading(false);
970
+ if (onError) onError(new Error(errorMsg));
971
+ return { data: null, error: errorMsg };
972
+ }
973
+ const sseResult = await client.sse.post({
974
+ baseUrl,
975
+ url: "/api/v1/chat/completions",
976
+ body: {
977
+ messages,
978
+ model,
979
+ stream: true
980
+ },
981
+ headers: {
982
+ "Content-Type": "application/json",
983
+ Authorization: `Bearer ${token}`
984
+ },
985
+ signal: abortController.signal
986
+ });
987
+ let accumulatedContent = "";
988
+ let completionId = "";
989
+ let completionModel = "";
990
+ let accumulatedUsage = {};
991
+ let finishReason;
992
+ for await (const chunk of sseResult.stream) {
993
+ if (typeof chunk === "string" && (chunk.trim() === "[DONE]" || chunk.includes("[DONE]"))) {
994
+ continue;
915
995
  }
916
- if (chunkData.choices && Array.isArray(chunkData.choices) && chunkData.choices.length > 0) {
917
- const choice = chunkData.choices[0];
918
- if (choice.delta?.content) {
919
- const content = choice.delta.content;
920
- accumulatedContent += content;
921
- if (onData) {
922
- onData(content);
996
+ if (chunk && typeof chunk === "object") {
997
+ const chunkData = chunk;
998
+ if (chunkData.id && !completionId) {
999
+ completionId = chunkData.id;
1000
+ }
1001
+ if (chunkData.model && !completionModel) {
1002
+ completionModel = chunkData.model;
1003
+ }
1004
+ if (chunkData.usage) {
1005
+ accumulatedUsage = {
1006
+ ...accumulatedUsage,
1007
+ ...chunkData.usage
1008
+ };
1009
+ }
1010
+ if (chunkData.choices && Array.isArray(chunkData.choices) && chunkData.choices.length > 0) {
1011
+ const choice = chunkData.choices[0];
1012
+ if (choice.delta?.content) {
1013
+ const content = choice.delta.content;
1014
+ accumulatedContent += content;
1015
+ if (onData) {
1016
+ onData(content);
1017
+ }
1018
+ if (globalOnData) {
1019
+ globalOnData(content);
1020
+ }
923
1021
  }
924
- if (globalOnData) {
925
- globalOnData(content);
1022
+ if (choice.finish_reason) {
1023
+ finishReason = choice.finish_reason;
926
1024
  }
927
1025
  }
928
- if (choice.finish_reason) {
929
- finishReason = choice.finish_reason;
930
- }
931
1026
  }
932
1027
  }
1028
+ const completion = {
1029
+ id: completionId,
1030
+ model: completionModel,
1031
+ choices: [
1032
+ {
1033
+ index: 0,
1034
+ message: {
1035
+ role: "assistant",
1036
+ content: accumulatedContent
1037
+ },
1038
+ finish_reason: finishReason
1039
+ }
1040
+ ],
1041
+ usage: Object.keys(accumulatedUsage).length > 0 ? accumulatedUsage : void 0
1042
+ };
1043
+ setIsLoading(false);
1044
+ if (onFinish) {
1045
+ onFinish(completion);
1046
+ }
1047
+ return { data: completion, error: null };
933
1048
  }
934
- const completion = {
935
- id: completionId,
936
- model: completionModel,
937
- choices: [
938
- {
939
- index: 0,
940
- message: {
941
- role: "assistant",
942
- content: accumulatedContent
943
- },
944
- finish_reason: finishReason
945
- }
946
- ],
947
- usage: Object.keys(accumulatedUsage).length > 0 ? accumulatedUsage : void 0
948
- };
949
- setIsLoading(false);
950
- if (onFinish) {
951
- onFinish(completion);
952
- }
953
- return { data: completion, error: null };
954
1049
  } catch (err) {
955
1050
  if (err instanceof Error && err.name === "AbortError") {
956
1051
  setIsLoading(false);
@@ -969,7 +1064,15 @@ function useChat(options) {
969
1064
  }
970
1065
  }
971
1066
  },
972
- [getToken, baseUrl, globalOnData, onFinish, onError]
1067
+ [
1068
+ getToken,
1069
+ baseUrl,
1070
+ globalOnData,
1071
+ onFinish,
1072
+ onError,
1073
+ chatProvider,
1074
+ localModel
1075
+ ]
973
1076
  );
974
1077
  return {
975
1078
  isLoading,
@@ -1372,37 +1475,61 @@ var getApiV1Models = (options) => {
1372
1475
  });
1373
1476
  };
1374
1477
 
1478
+ // src/lib/memory/constants.ts
1479
+ var DEFAULT_LOCAL_EMBEDDING_MODEL = "Snowflake/snowflake-arctic-embed-xs";
1480
+ var DEFAULT_API_EMBEDDING_MODEL = "openai/text-embedding-3-small";
1481
+ var DEFAULT_COMPLETION_MODEL = "openai/gpt-4o";
1482
+
1375
1483
  // src/lib/memory/embeddings.ts
1484
+ var embeddingPipeline = null;
1376
1485
  var generateEmbeddingForText = async (text, options = {}) => {
1377
- const {
1378
- model = "openai/text-embedding-3-small",
1379
- getToken,
1380
- baseUrl = BASE_URL
1381
- } = options;
1382
- try {
1383
- const token = getToken ? await getToken() : null;
1384
- const headers = {};
1385
- if (token) {
1386
- headers.Authorization = `Bearer ${token}`;
1486
+ const { baseUrl = BASE_URL, provider = "local" } = options;
1487
+ if (provider === "api") {
1488
+ const { getToken, model: model2 } = options;
1489
+ if (!getToken) {
1490
+ throw new Error("getToken is required for API embeddings");
1491
+ }
1492
+ const token = await getToken();
1493
+ if (!token) {
1494
+ throw new Error("No access token available for API embeddings");
1387
1495
  }
1388
1496
  const response = await postApiV1Embeddings({
1389
1497
  baseUrl,
1390
1498
  body: {
1391
1499
  input: text,
1392
- model
1500
+ model: model2
1393
1501
  },
1394
- headers
1502
+ headers: {
1503
+ Authorization: `Bearer ${token}`
1504
+ }
1395
1505
  });
1396
- if (!response.data || !response.data.data || response.data.data.length === 0) {
1506
+ if (response.error) {
1397
1507
  throw new Error(
1398
- `Failed to generate embedding: ${response.error?.error ?? "No data returned"}`
1508
+ typeof response.error === "object" && response.error && "error" in response.error ? response.error.error : "API embedding failed"
1399
1509
  );
1400
1510
  }
1401
- const embedding = response.data.data[0]?.embedding;
1402
- if (!embedding || !Array.isArray(embedding)) {
1403
- throw new Error("Invalid embedding format returned from API");
1511
+ if (!response.data?.data?.[0]?.embedding) {
1512
+ throw new Error("No embedding returned from API");
1513
+ }
1514
+ return response.data.data[0].embedding;
1515
+ }
1516
+ let { model } = options;
1517
+ if (!model || model === DEFAULT_API_EMBEDDING_MODEL) {
1518
+ model = DEFAULT_LOCAL_EMBEDDING_MODEL;
1519
+ }
1520
+ try {
1521
+ if (!embeddingPipeline) {
1522
+ const { pipeline } = await import("./transformers.node-BSHUG7OY.mjs");
1523
+ embeddingPipeline = await pipeline("feature-extraction", model);
1524
+ }
1525
+ const output = await embeddingPipeline(text, {
1526
+ pooling: "cls",
1527
+ normalize: true
1528
+ });
1529
+ if (output?.data) {
1530
+ return Array.from(output.data);
1404
1531
  }
1405
- return embedding;
1532
+ throw new Error("Invalid embedding output from transformers.js");
1406
1533
  } catch (error) {
1407
1534
  console.error("Failed to generate embedding:", error);
1408
1535
  throw error;
@@ -1419,20 +1546,11 @@ var generateEmbeddingForMemory = async (memory, options = {}) => {
1419
1546
  return generateEmbeddingForText(text, options);
1420
1547
  };
1421
1548
  var generateEmbeddingsForMemories = async (memories, options = {}) => {
1422
- const {
1423
- model = "openai/text-embedding-3-small",
1424
- getToken,
1425
- baseUrl = BASE_URL
1426
- } = options;
1427
1549
  const embeddings = /* @__PURE__ */ new Map();
1428
1550
  for (const memory of memories) {
1429
1551
  const uniqueKey = `${memory.namespace}:${memory.key}:${memory.value}`;
1430
1552
  try {
1431
- const embedding = await generateEmbeddingForMemory(memory, {
1432
- model,
1433
- getToken,
1434
- baseUrl
1435
- });
1553
+ const embedding = await generateEmbeddingForMemory(memory, options);
1436
1554
  embeddings.set(uniqueKey, embedding);
1437
1555
  } catch (error) {
1438
1556
  console.error(
@@ -1464,29 +1582,42 @@ var updateMemoriesWithEmbeddings = async (embeddings, embeddingModel) => {
1464
1582
  await Promise.all(updates);
1465
1583
  };
1466
1584
  var generateAndStoreEmbeddings = async (memories, options = {}) => {
1467
- const { model = "openai/text-embedding-3-small" } = options;
1585
+ let { model } = options;
1586
+ const { provider = "local" } = options;
1587
+ if (!model) {
1588
+ if (provider === "local") {
1589
+ model = DEFAULT_LOCAL_EMBEDDING_MODEL;
1590
+ } else {
1591
+ model = DEFAULT_API_EMBEDDING_MODEL;
1592
+ }
1593
+ }
1594
+ if (provider === "local" && model === DEFAULT_API_EMBEDDING_MODEL) {
1595
+ model = DEFAULT_LOCAL_EMBEDDING_MODEL;
1596
+ }
1468
1597
  if (memories.length === 0) {
1469
1598
  return;
1470
1599
  }
1471
1600
  console.log(`Generating embeddings for ${memories.length} memories...`);
1472
- const embeddings = await generateEmbeddingsForMemories(memories, options);
1601
+ const embeddings = await generateEmbeddingsForMemories(memories, {
1602
+ ...options,
1603
+ model
1604
+ });
1473
1605
  await updateMemoriesWithEmbeddings(embeddings, model);
1474
1606
  console.log(`Generated and stored ${embeddings.size} embeddings`);
1475
1607
  };
1476
- var generateQueryEmbedding = async (query, options = {}) => {
1477
- return generateEmbeddingForText(query, options);
1478
- };
1479
1608
 
1480
1609
  // src/react/useMemory.ts
1481
1610
  function useMemory(options = {}) {
1482
1611
  const {
1483
- memoryModel = "openai/gpt-4o",
1484
- embeddingModel = "openai/text-embedding-3-small",
1612
+ completionsModel = DEFAULT_COMPLETION_MODEL,
1613
+ embeddingModel: userEmbeddingModel,
1614
+ embeddingProvider = "local",
1485
1615
  generateEmbeddings = true,
1486
1616
  onFactsExtracted,
1487
1617
  getToken,
1488
1618
  baseUrl = BASE_URL
1489
1619
  } = options;
1620
+ const embeddingModel = userEmbeddingModel === void 0 ? embeddingProvider === "local" ? DEFAULT_LOCAL_EMBEDDING_MODEL : DEFAULT_API_EMBEDDING_MODEL : userEmbeddingModel;
1490
1621
  const extractionInProgressRef = useRef3(false);
1491
1622
  const extractMemoriesFromMessage = useCallback2(
1492
1623
  async (options2) => {
@@ -1511,7 +1642,7 @@ function useMemory(options = {}) {
1511
1642
  },
1512
1643
  ...messages
1513
1644
  ],
1514
- model: model || memoryModel
1645
+ model: model || completionsModel
1515
1646
  },
1516
1647
  headers: {
1517
1648
  Authorization: `Bearer ${token}`
@@ -1626,6 +1757,7 @@ function useMemory(options = {}) {
1626
1757
  try {
1627
1758
  await generateAndStoreEmbeddings(result.items, {
1628
1759
  model: embeddingModel,
1760
+ provider: embeddingProvider,
1629
1761
  getToken: getToken || void 0,
1630
1762
  baseUrl
1631
1763
  });
@@ -1652,8 +1784,9 @@ function useMemory(options = {}) {
1652
1784
  }
1653
1785
  },
1654
1786
  [
1655
- memoryModel,
1787
+ completionsModel,
1656
1788
  embeddingModel,
1789
+ embeddingProvider,
1657
1790
  generateEmbeddings,
1658
1791
  getToken,
1659
1792
  onFactsExtracted,
@@ -1662,16 +1795,15 @@ function useMemory(options = {}) {
1662
1795
  );
1663
1796
  const searchMemories = useCallback2(
1664
1797
  async (query, limit = 10, minSimilarity = 0.6) => {
1665
- if (!getToken || !embeddingModel) {
1666
- console.warn(
1667
- "Cannot search memories: getToken or embeddingModel not provided"
1668
- );
1798
+ if (!embeddingModel) {
1799
+ console.warn("Cannot search memories: embeddingModel not provided");
1669
1800
  return [];
1670
1801
  }
1671
1802
  try {
1672
1803
  console.log(`[Memory Search] Searching for: "${query}"`);
1673
- const queryEmbedding = await generateQueryEmbedding(query, {
1804
+ const queryEmbedding = await generateEmbeddingForText(query, {
1674
1805
  model: embeddingModel,
1806
+ provider: embeddingProvider,
1675
1807
  getToken,
1676
1808
  baseUrl
1677
1809
  });
@@ -1698,7 +1830,7 @@ function useMemory(options = {}) {
1698
1830
  return [];
1699
1831
  }
1700
1832
  },
1701
- [embeddingModel, getToken, baseUrl]
1833
+ [embeddingModel, embeddingProvider, getToken, baseUrl]
1702
1834
  );
1703
1835
  return {
1704
1836
  extractMemoriesFromMessage,