@tryhamster/gerbil 1.0.0-rc.11 → 1.0.0-rc.12

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 (57) hide show
  1. package/README.md +28 -1
  2. package/dist/browser/index.d.ts +98 -1
  3. package/dist/browser/index.d.ts.map +1 -1
  4. package/dist/browser/index.js +311 -1
  5. package/dist/browser/index.js.map +1 -1
  6. package/dist/cli.mjs +7 -7
  7. package/dist/cli.mjs.map +1 -1
  8. package/dist/frameworks/express.d.mts +1 -1
  9. package/dist/frameworks/express.mjs +1 -1
  10. package/dist/frameworks/fastify.d.mts +1 -1
  11. package/dist/frameworks/fastify.mjs +1 -1
  12. package/dist/frameworks/hono.d.mts +1 -1
  13. package/dist/frameworks/hono.mjs +1 -1
  14. package/dist/frameworks/next.d.mts +2 -2
  15. package/dist/frameworks/next.mjs +1 -1
  16. package/dist/frameworks/react.d.mts +1 -1
  17. package/dist/frameworks/react.d.mts.map +1 -1
  18. package/dist/frameworks/trpc.d.mts +1 -1
  19. package/dist/frameworks/trpc.mjs +1 -1
  20. package/dist/{gerbil-DoDGHe6Z.mjs → gerbil-BcWjCGtM.mjs} +83 -1
  21. package/dist/{gerbil-DoDGHe6Z.mjs.map → gerbil-BcWjCGtM.mjs.map} +1 -1
  22. package/dist/gerbil-CBQkuQ9i.mjs +4 -0
  23. package/dist/{gerbil-qOTe1nl2.d.mts → gerbil-E12cYLNi.d.mts} +51 -2
  24. package/dist/gerbil-E12cYLNi.d.mts.map +1 -0
  25. package/dist/index.d.mts +3 -3
  26. package/dist/index.d.mts.map +1 -1
  27. package/dist/index.mjs +2 -2
  28. package/dist/index.mjs.map +1 -1
  29. package/dist/integrations/ai-sdk.d.mts +57 -3
  30. package/dist/integrations/ai-sdk.d.mts.map +1 -1
  31. package/dist/integrations/ai-sdk.mjs +88 -2
  32. package/dist/integrations/ai-sdk.mjs.map +1 -1
  33. package/dist/integrations/langchain.d.mts +1 -1
  34. package/dist/integrations/langchain.mjs +1 -1
  35. package/dist/integrations/llamaindex.d.mts +1 -1
  36. package/dist/integrations/llamaindex.mjs +1 -1
  37. package/dist/integrations/mcp.d.mts +2 -2
  38. package/dist/integrations/mcp.mjs +4 -4
  39. package/dist/{mcp-kzDDWIoS.mjs → mcp-DXqxF7ri.mjs} +3 -3
  40. package/dist/{mcp-kzDDWIoS.mjs.map → mcp-DXqxF7ri.mjs.map} +1 -1
  41. package/dist/{one-liner-DxnNs_JK.mjs → one-liner-UtQX47IT.mjs} +2 -2
  42. package/dist/{one-liner-DxnNs_JK.mjs.map → one-liner-UtQX47IT.mjs.map} +1 -1
  43. package/dist/{repl-DGUw4fCc.mjs → repl-FjIaBVFD.mjs} +3 -3
  44. package/dist/skills/index.d.mts +6 -6
  45. package/dist/skills/index.d.mts.map +1 -1
  46. package/dist/skills/index.mjs +3 -3
  47. package/dist/{skills-DulrOPeP.mjs → skills-BmlseBpJ.mjs} +2 -2
  48. package/dist/{skills-DulrOPeP.mjs.map → skills-BmlseBpJ.mjs.map} +1 -1
  49. package/dist/{types-CiTc7ez3.d.mts → types-Bgb_89Bh.d.mts} +20 -2
  50. package/dist/types-Bgb_89Bh.d.mts.map +1 -0
  51. package/docs/ai-sdk.md +38 -1
  52. package/docs/browser.md +69 -0
  53. package/docs/embeddings.md +311 -0
  54. package/package.json +1 -1
  55. package/dist/gerbil-DJGqq7BX.mjs +0 -4
  56. package/dist/gerbil-qOTe1nl2.d.mts.map +0 -1
  57. package/dist/types-CiTc7ez3.d.mts.map +0 -1
package/README.md CHANGED
@@ -11,6 +11,7 @@
11
11
  <p align="center">
12
12
  <a href="#install">Install</a> •
13
13
  <a href="#quick-start">Quick Start</a> •
14
+ <a href="#embeddings">Embeddings</a> •
14
15
  <a href="#text-to-speech">TTS</a> •
15
16
  <a href="#speech-to-text">STT</a> •
16
17
  <a href="./docs/vision.md">Vision</a> •
@@ -46,6 +47,7 @@ const text = await gerbil("Explain recursion in one sentence");
46
47
  - **Zero Config** — `npx @tryhamster/gerbil "your prompt"` just works
47
48
  - **Local & Private** — No API keys, no data leaves your machine
48
49
  - **GPU Accelerated** — WebGPU with CPU fallback
50
+ - **Embeddings** — Semantic search, similarity, RAG
49
51
  - **Vision** — Analyze images with Ministral 3B
50
52
  - **Complete Audio** — Text-to-Speech (Kokoro/Supertonic) & Speech-to-Text (Whisper)
51
53
  - **Framework Ready** — AI SDK v5, Next.js, Express, LangChain
@@ -95,6 +97,30 @@ const data = await g.json("Extract: John, 32, NYC", {
95
97
  });
96
98
  ```
97
99
 
100
+ ## Embeddings
101
+
102
+ Generate semantic embeddings for search, similarity, and RAG:
103
+
104
+ ```typescript
105
+ // Compare two texts
106
+ const similarity = await g.similarity("Hello world", "Hi there");
107
+ console.log(similarity.score); // 0.85
108
+
109
+ // Semantic search
110
+ const results = await g.search("capital of France", [
111
+ "Paris is beautiful",
112
+ "London is in England",
113
+ "Dogs are pets"
114
+ ]);
115
+ // [{ text: "Paris is beautiful", score: 0.89, index: 0 }, ...]
116
+
117
+ // Generate embedding vector
118
+ const { vector } = await g.embed("Hello world");
119
+ // number[384]
120
+ ```
121
+
122
+ 📖 **[Full Embeddings Documentation →](./docs/embeddings.md)**
123
+
98
124
  ## Text-to-Speech
99
125
 
100
126
  Generate natural speech locally using Kokoro TTS (28 voices):
@@ -298,6 +324,7 @@ Use any HuggingFace model: `npx @tryhamster/gerbil -m hf:org/model "prompt"`
298
324
 
299
325
  | Guide | Description |
300
326
  |-------|-------------|
327
+ | [📖 Embeddings](./docs/embeddings.md) | Semantic search, similarity, RAG |
301
328
  | [📖 Vision](./docs/vision.md) | Image analysis with Ministral 3B |
302
329
  | [📖 Text-to-Speech](./docs/tts.md) | Kokoro & Supertonic TTS, streaming audio |
303
330
  | [📖 Speech-to-Text](./docs/stt.md) | Whisper STT, transcription, voice input |
@@ -305,7 +332,7 @@ Use any HuggingFace model: `npx @tryhamster/gerbil -m hf:org/model "prompt"`
305
332
  | [📖 Skills](./docs/skills.md) | Built-in skills, custom skill development |
306
333
  | [📖 Tools](./docs/tools.md) | Tool calling, agentic workflows |
307
334
  | [📖 REPL](./docs/repl.md) | Interactive terminal dashboard |
308
- | [📖 AI SDK](./docs/ai-sdk.md) | Vercel AI SDK v5 (LLM, TTS, STT) |
335
+ | [📖 AI SDK](./docs/ai-sdk.md) | Vercel AI SDK v5 (LLM, TTS, STT, Embeddings) |
309
336
  | [📖 Frameworks](./docs/frameworks.md) | Next.js, Express, React, LangChain |
310
337
  | [📖 CLI](./docs/cli.md) | All CLI commands and options |
311
338
  | [📖 MCP Server](./docs/mcp.md) | MCP server for Claude Desktop & Cursor |
@@ -92,6 +92,24 @@ type EmbedResult = {
92
92
  /** Time in ms */
93
93
  totalTime: number;
94
94
  };
95
+ type SearchResult = {
96
+ /** The matched text */
97
+ text: string;
98
+ /** Similarity score (0-1, higher is more similar) */
99
+ score: number;
100
+ /** Index in the original corpus */
101
+ index: number;
102
+ };
103
+ type SimilarityResult = {
104
+ /** Similarity score (0-1, higher is more similar) */
105
+ score: number;
106
+ /** First text */
107
+ textA: string;
108
+ /** Second text */
109
+ textB: string;
110
+ /** Time in ms */
111
+ totalTime: number;
112
+ };
95
113
  type LoadOptions = {
96
114
  /** Progress callback */
97
115
  onProgress?: (info: ProgressInfo) => void;
@@ -985,6 +1003,85 @@ type UseVoiceChatReturn = {
985
1003
  * ```
986
1004
  */
987
1005
  declare function useVoiceChat(options?: UseVoiceChatOptions): UseVoiceChatReturn;
1006
+ /** Embedding result type */
1007
+ type BrowserEmbedResult = {
1008
+ vector: number[];
1009
+ text: string;
1010
+ };
1011
+ /** Search result type */
1012
+ type BrowserSearchResult = {
1013
+ text: string;
1014
+ score: number;
1015
+ index: number;
1016
+ };
1017
+ /** useEmbedding options */
1018
+ type UseEmbeddingOptions = {
1019
+ /** Embedding model (default: "Xenova/all-MiniLM-L6-v2") */
1020
+ model?: string;
1021
+ /** Normalize vectors (default: true) */
1022
+ normalize?: boolean;
1023
+ /** Auto-load on mount (default: false) */
1024
+ autoLoad?: boolean;
1025
+ /** Callback when ready */
1026
+ onReady?: () => void;
1027
+ /** Callback on error */
1028
+ onError?: (error: string) => void;
1029
+ };
1030
+ /** useEmbedding return type */
1031
+ type UseEmbeddingReturn = {
1032
+ /** Generate embedding for text */
1033
+ embed: (text: string) => Promise<number[]>;
1034
+ /** Generate embeddings for multiple texts */
1035
+ embedBatch: (texts: string[]) => Promise<BrowserEmbedResult[]>;
1036
+ /** Compute cosine similarity between two texts */
1037
+ similarity: (textA: string, textB: string) => Promise<number>;
1038
+ /** Semantic search - find most similar texts */
1039
+ search: (query: string, corpus: string[], topK?: number) => Promise<BrowserSearchResult[]>;
1040
+ /** Find nearest text to an embedding vector */
1041
+ findNearest: (embedding: number[], candidates: string[], topK?: number) => Promise<BrowserSearchResult[]>;
1042
+ /** Compute cosine similarity between two vectors */
1043
+ cosineSimilarity: (a: number[], b: number[]) => number;
1044
+ /** Manually load the model */
1045
+ load: () => void;
1046
+ /** Whether model is loading */
1047
+ isLoading: boolean;
1048
+ /** Whether model is ready */
1049
+ isReady: boolean;
1050
+ /** Loading progress */
1051
+ loadingProgress: {
1052
+ status: string;
1053
+ message?: string;
1054
+ progress?: number;
1055
+ } | null;
1056
+ /** Error message */
1057
+ error: string | null;
1058
+ };
1059
+ /**
1060
+ * React hook for text embeddings in the browser
1061
+ *
1062
+ * @example
1063
+ * ```tsx
1064
+ * import { useEmbedding } from "@tryhamster/gerbil/browser";
1065
+ *
1066
+ * function App() {
1067
+ * const { embed, similarity, search, isLoading, isReady } = useEmbedding();
1068
+ *
1069
+ * if (isLoading) return <div>Loading embedding model...</div>;
1070
+ *
1071
+ * const handleSearch = async () => {
1072
+ * const results = await search("capital of France", [
1073
+ * "Paris is beautiful",
1074
+ * "London is in England",
1075
+ * "Dogs are pets"
1076
+ * ]);
1077
+ * console.log(results); // [{ text: "Paris is beautiful", score: 0.89, index: 0 }, ...]
1078
+ * };
1079
+ *
1080
+ * return <button onClick={handleSearch}>Search</button>;
1081
+ * }
1082
+ * ```
1083
+ */
1084
+ declare function useEmbedding(options?: UseEmbeddingOptions): UseEmbeddingReturn;
988
1085
  /**
989
1086
  * Check if WebGPU is supported
990
1087
  */
@@ -1005,5 +1102,5 @@ declare const _default: {
1005
1102
  createAudioPlayer: typeof createAudioPlayer;
1006
1103
  };
1007
1104
  //#endregion
1008
- export { AudioChunk, BUILTIN_MODELS, BrowserVoiceInfo, CacheConfig, CompleteOptions, EmbedOptions, EmbedResult, FallbackConfig, GenerateOptions, GenerateResult, GenerateStreamOptions, GerbilConfig, GerbilModelSettings, GerbilProviderSettings, GerbilWorker, GerbilWorkerOptions, ImageInput, JsonOptions, LoadOptions, LoadSTTOptions, LoadTTSOptions, LoadingProgress, Message, ModelConfig, ModelSource, ModelStats, ProgressInfo, STTModelConfig, STTProgress, SessionStats, SpeakOptions, SpeakResult, StreamingTranscriptionOptions, StreamingTranscriptionSession, SystemInfo, TTSModelConfig, TTSModelId, TTSProgress, TranscribeOptions, TranscribeResult, TranscribeSegment, UseChatOptions, UseChatReturn, UseCompletionOptions, UseCompletionReturn, UseSpeechOptions, UseSpeechReturn, UseVoiceChatOptions, UseVoiceChatReturn, UseVoiceInputOptions, UseVoiceInputReturn, VoiceChatMessage, VoiceInfo, WorkerComplete, WorkerProgress, WorkerToken, createAudioPlayer, createGerbilWorker, _default as default, getWebGPUInfo, isWebGPUSupported, playAudio, useChat, useCompletion, useSpeech, useVoiceChat, useVoiceInput };
1105
+ export { AudioChunk, BUILTIN_MODELS, BrowserEmbedResult, BrowserSearchResult, BrowserVoiceInfo, CacheConfig, CompleteOptions, EmbedOptions, EmbedResult, FallbackConfig, GenerateOptions, GenerateResult, GenerateStreamOptions, GerbilConfig, GerbilModelSettings, GerbilProviderSettings, GerbilWorker, GerbilWorkerOptions, ImageInput, JsonOptions, LoadOptions, LoadSTTOptions, LoadTTSOptions, LoadingProgress, Message, ModelConfig, ModelSource, ModelStats, ProgressInfo, STTModelConfig, STTProgress, SearchResult, SessionStats, SimilarityResult, SpeakOptions, SpeakResult, StreamingTranscriptionOptions, StreamingTranscriptionSession, SystemInfo, TTSModelConfig, TTSModelId, TTSProgress, TranscribeOptions, TranscribeResult, TranscribeSegment, UseChatOptions, UseChatReturn, UseCompletionOptions, UseCompletionReturn, UseEmbeddingOptions, UseEmbeddingReturn, UseSpeechOptions, UseSpeechReturn, UseVoiceChatOptions, UseVoiceChatReturn, UseVoiceInputOptions, UseVoiceInputReturn, VoiceChatMessage, VoiceInfo, WorkerComplete, WorkerProgress, WorkerToken, createAudioPlayer, createGerbilWorker, _default as default, getWebGPUInfo, isWebGPUSupported, playAudio, useChat, useCompletion, useEmbedding, useSpeech, useVoiceChat, useVoiceInput };
1009
1106
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/core/types.ts","../../src/core/models.ts","../../src/browser/index.ts"],"sourcesContent":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/core/types.ts","../../src/core/models.ts","../../src/browser/index.ts"],"sourcesContent":[],"mappings":"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"}
@@ -2715,6 +2715,316 @@ function useVoiceChat(options = {}) {
2715
2715
  load
2716
2716
  };
2717
2717
  }
2718
+ const EMBEDDING_WORKER_CODE = `
2719
+ // Embedding Worker - runs in separate thread, loads from CDN
2720
+ import { pipeline, env } from "https://cdn.jsdelivr.net/npm/@huggingface/transformers@3.8.1";
2721
+
2722
+ // Configure environment
2723
+ env.useBrowserCache = true;
2724
+ env.allowLocalModels = false;
2725
+
2726
+ let embedder = null;
2727
+ let modelId = null;
2728
+
2729
+ self.onmessage = async (e) => {
2730
+ const { type, payload } = e.data;
2731
+
2732
+ if (type === "load") {
2733
+ try {
2734
+ modelId = payload.model || "Xenova/all-MiniLM-L6-v2";
2735
+
2736
+ embedder = await pipeline("feature-extraction", modelId, {
2737
+ progress_callback: (progress) => {
2738
+ self.postMessage({ type: "progress", payload: progress });
2739
+ },
2740
+ });
2741
+
2742
+ // Warmup
2743
+ try {
2744
+ await embedder("hello", { pooling: "mean", normalize: true });
2745
+ } catch (e) {
2746
+ console.warn("Embedding warmup failed:", e);
2747
+ }
2748
+
2749
+ self.postMessage({ type: "ready" });
2750
+ } catch (err) {
2751
+ self.postMessage({ type: "error", payload: err.message || String(err) });
2752
+ }
2753
+ }
2754
+
2755
+ if (type === "embed") {
2756
+ try {
2757
+ const { text, normalize } = payload;
2758
+ const output = await embedder(text, {
2759
+ pooling: "mean",
2760
+ normalize: normalize !== false,
2761
+ });
2762
+
2763
+ const vector = Array.from(output.data);
2764
+ self.postMessage({ type: "embedding", payload: { vector, text } });
2765
+ } catch (err) {
2766
+ self.postMessage({ type: "error", payload: err.message || String(err) });
2767
+ }
2768
+ }
2769
+
2770
+ if (type === "embedBatch") {
2771
+ try {
2772
+ const { texts, normalize } = payload;
2773
+ const results = [];
2774
+
2775
+ for (const text of texts) {
2776
+ const output = await embedder(text, {
2777
+ pooling: "mean",
2778
+ normalize: normalize !== false,
2779
+ });
2780
+ results.push({ vector: Array.from(output.data), text });
2781
+ }
2782
+
2783
+ self.postMessage({ type: "embeddings", payload: results });
2784
+ } catch (err) {
2785
+ self.postMessage({ type: "error", payload: err.message || String(err) });
2786
+ }
2787
+ }
2788
+ };
2789
+ `;
2790
+ /** Create Embedding worker instance */
2791
+ function createEmbeddingWorker() {
2792
+ const blob = new Blob([EMBEDDING_WORKER_CODE], { type: "application/javascript" });
2793
+ const url = URL.createObjectURL(blob);
2794
+ const worker = new Worker(url, { type: "module" });
2795
+ URL.revokeObjectURL(url);
2796
+ return worker;
2797
+ }
2798
+ /**
2799
+ * React hook for text embeddings in the browser
2800
+ *
2801
+ * @example
2802
+ * ```tsx
2803
+ * import { useEmbedding } from "@tryhamster/gerbil/browser";
2804
+ *
2805
+ * function App() {
2806
+ * const { embed, similarity, search, isLoading, isReady } = useEmbedding();
2807
+ *
2808
+ * if (isLoading) return <div>Loading embedding model...</div>;
2809
+ *
2810
+ * const handleSearch = async () => {
2811
+ * const results = await search("capital of France", [
2812
+ * "Paris is beautiful",
2813
+ * "London is in England",
2814
+ * "Dogs are pets"
2815
+ * ]);
2816
+ * console.log(results); // [{ text: "Paris is beautiful", score: 0.89, index: 0 }, ...]
2817
+ * };
2818
+ *
2819
+ * return <button onClick={handleSearch}>Search</button>;
2820
+ * }
2821
+ * ```
2822
+ */
2823
+ function useEmbedding(options = {}) {
2824
+ const React = globalThis.React;
2825
+ if (!React) throw new Error("useEmbedding requires React. Make sure React is available in the global scope.");
2826
+ const { useState, useEffect, useRef, useCallback } = React;
2827
+ const { model = "Xenova/all-MiniLM-L6-v2", normalize = true, autoLoad = false, onReady, onError } = options;
2828
+ const [isLoading, setIsLoading] = useState(false);
2829
+ const [isReady, setIsReady] = useState(false);
2830
+ const [error, setError] = useState(null);
2831
+ const [loadingProgress, setLoadingProgress] = useState(null);
2832
+ const workerRef = useRef(null);
2833
+ const loadRequestedRef = useRef(false);
2834
+ const pendingRequestsRef = useRef(/* @__PURE__ */ new Map());
2835
+ const cosineSimilarity = useCallback((a, b) => {
2836
+ if (a.length !== b.length) throw new Error(`Vector dimensions must match: ${a.length} vs ${b.length}`);
2837
+ let dotProduct = 0;
2838
+ let normA = 0;
2839
+ let normB = 0;
2840
+ for (let i = 0; i < a.length; i++) {
2841
+ dotProduct += a[i] * b[i];
2842
+ normA += a[i] * a[i];
2843
+ normB += b[i] * b[i];
2844
+ }
2845
+ const magnitude = Math.sqrt(normA) * Math.sqrt(normB);
2846
+ if (magnitude === 0) return 0;
2847
+ return dotProduct / magnitude;
2848
+ }, []);
2849
+ const load = useCallback(() => {
2850
+ if (loadRequestedRef.current || isReady) return;
2851
+ loadRequestedRef.current = true;
2852
+ setIsLoading(true);
2853
+ setLoadingProgress({
2854
+ status: "loading",
2855
+ message: "Loading embedding model..."
2856
+ });
2857
+ const worker = createEmbeddingWorker();
2858
+ workerRef.current = worker;
2859
+ worker.onmessage = (e) => {
2860
+ const { type, payload } = e.data;
2861
+ if (type === "progress") {
2862
+ if (payload.status === "progress" && payload.file) setLoadingProgress({
2863
+ status: "downloading",
2864
+ message: `Downloading ${payload.file}`,
2865
+ progress: Math.round(payload.loaded / payload.total * 100)
2866
+ });
2867
+ } else if (type === "ready") {
2868
+ setIsLoading(false);
2869
+ setIsReady(true);
2870
+ setLoadingProgress({ status: "ready" });
2871
+ onReady?.();
2872
+ } else if (type === "error") {
2873
+ setIsLoading(false);
2874
+ setError(payload);
2875
+ onError?.(payload);
2876
+ } else if (type === "embedding" || type === "embeddings") {
2877
+ const pending = pendingRequestsRef.current.get(type);
2878
+ if (pending) {
2879
+ pending.resolve(payload);
2880
+ pendingRequestsRef.current.delete(type);
2881
+ }
2882
+ }
2883
+ };
2884
+ worker.postMessage({
2885
+ type: "load",
2886
+ payload: { model }
2887
+ });
2888
+ }, [
2889
+ model,
2890
+ isReady,
2891
+ onReady,
2892
+ onError
2893
+ ]);
2894
+ useEffect(() => {
2895
+ if (autoLoad) load();
2896
+ return () => {
2897
+ if (workerRef.current) {
2898
+ workerRef.current.terminate();
2899
+ workerRef.current = null;
2900
+ }
2901
+ };
2902
+ }, [autoLoad, load]);
2903
+ const embed = useCallback(async (text) => {
2904
+ if (!isReady) {
2905
+ load();
2906
+ await new Promise((resolve) => {
2907
+ const checkReady = setInterval(() => {
2908
+ if (workerRef.current) {
2909
+ const handler = (e) => {
2910
+ if (e.data.type === "ready") {
2911
+ clearInterval(checkReady);
2912
+ resolve();
2913
+ }
2914
+ };
2915
+ workerRef.current.addEventListener("message", handler, { once: true });
2916
+ }
2917
+ }, 100);
2918
+ });
2919
+ }
2920
+ return new Promise((resolve, reject) => {
2921
+ const worker = workerRef.current;
2922
+ if (!worker) {
2923
+ reject(/* @__PURE__ */ new Error("Worker not initialized"));
2924
+ return;
2925
+ }
2926
+ const handler = (e) => {
2927
+ if (e.data.type === "embedding") {
2928
+ worker.removeEventListener("message", handler);
2929
+ resolve(e.data.payload.vector);
2930
+ } else if (e.data.type === "error") {
2931
+ worker.removeEventListener("message", handler);
2932
+ reject(new Error(e.data.payload));
2933
+ }
2934
+ };
2935
+ worker.addEventListener("message", handler);
2936
+ worker.postMessage({
2937
+ type: "embed",
2938
+ payload: {
2939
+ text,
2940
+ normalize
2941
+ }
2942
+ });
2943
+ });
2944
+ }, [
2945
+ isReady,
2946
+ load,
2947
+ normalize
2948
+ ]);
2949
+ const embedBatch = useCallback(async (texts) => {
2950
+ if (!isReady) {
2951
+ load();
2952
+ await new Promise((resolve) => {
2953
+ const check = setInterval(() => {
2954
+ if (isReady) {
2955
+ clearInterval(check);
2956
+ resolve();
2957
+ }
2958
+ }, 100);
2959
+ });
2960
+ }
2961
+ return new Promise((resolve, reject) => {
2962
+ const worker = workerRef.current;
2963
+ if (!worker) {
2964
+ reject(/* @__PURE__ */ new Error("Worker not initialized"));
2965
+ return;
2966
+ }
2967
+ const handler = (e) => {
2968
+ if (e.data.type === "embeddings") {
2969
+ worker.removeEventListener("message", handler);
2970
+ resolve(e.data.payload);
2971
+ } else if (e.data.type === "error") {
2972
+ worker.removeEventListener("message", handler);
2973
+ reject(new Error(e.data.payload));
2974
+ }
2975
+ };
2976
+ worker.addEventListener("message", handler);
2977
+ worker.postMessage({
2978
+ type: "embedBatch",
2979
+ payload: {
2980
+ texts,
2981
+ normalize
2982
+ }
2983
+ });
2984
+ });
2985
+ }, [
2986
+ isReady,
2987
+ load,
2988
+ normalize
2989
+ ]);
2990
+ return {
2991
+ embed,
2992
+ embedBatch,
2993
+ similarity: useCallback(async (textA, textB) => {
2994
+ const [embA, embB] = await Promise.all([embed(textA), embed(textB)]);
2995
+ return cosineSimilarity(embA, embB);
2996
+ }, [embed, cosineSimilarity]),
2997
+ search: useCallback(async (query, corpus, topK) => {
2998
+ const [queryEmb, corpusEmbs] = await Promise.all([embed(query), embedBatch(corpus)]);
2999
+ const results = corpusEmbs.map((doc, index) => ({
3000
+ text: doc.text,
3001
+ score: cosineSimilarity(queryEmb, doc.vector),
3002
+ index
3003
+ }));
3004
+ results.sort((a, b) => b.score - a.score);
3005
+ return topK ? results.slice(0, topK) : results;
3006
+ }, [
3007
+ embed,
3008
+ embedBatch,
3009
+ cosineSimilarity
3010
+ ]),
3011
+ findNearest: useCallback(async (embedding, candidates, topK) => {
3012
+ const results = (await embedBatch(candidates)).map((doc, index) => ({
3013
+ text: doc.text,
3014
+ score: cosineSimilarity(embedding, doc.vector),
3015
+ index
3016
+ }));
3017
+ results.sort((a, b) => b.score - a.score);
3018
+ return topK ? results.slice(0, topK) : results;
3019
+ }, [embedBatch, cosineSimilarity]),
3020
+ cosineSimilarity,
3021
+ load,
3022
+ isLoading,
3023
+ isReady,
3024
+ loadingProgress,
3025
+ error
3026
+ };
3027
+ }
2718
3028
  /**
2719
3029
  * Check if WebGPU is supported
2720
3030
  */
@@ -2749,5 +3059,5 @@ var browser_default = {
2749
3059
  };
2750
3060
 
2751
3061
  //#endregion
2752
- export { BUILTIN_MODELS, createAudioPlayer, createGerbilWorker, browser_default as default, getWebGPUInfo, isWebGPUSupported, playAudio, useChat, useCompletion, useSpeech, useVoiceChat, useVoiceInput };
3062
+ export { BUILTIN_MODELS, createAudioPlayer, createGerbilWorker, browser_default as default, getWebGPUInfo, isWebGPUSupported, playAudio, useChat, useCompletion, useEmbedding, useSpeech, useVoiceChat, useVoiceInput };
2753
3063
  //# sourceMappingURL=index.js.map