@browser-ai/web-llm 2.1.0 → 2.1.2

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.
package/dist/index.mjs CHANGED
@@ -957,7 +957,7 @@ ${existingContent}` : "")
957
957
  ];
958
958
  }
959
959
 
960
- // src/web-llm-language-model.ts
960
+ // src/utils/browser.ts
961
961
  function isMobile() {
962
962
  if (typeof navigator === "undefined") return false;
963
963
  return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
@@ -974,6 +974,8 @@ function checkWebGPU() {
974
974
  function doesBrowserSupportWebLLM() {
975
975
  return checkWebGPU();
976
976
  }
977
+
978
+ // src/web-llm-language-model.ts
977
979
  function extractToolName(content) {
978
980
  const jsonMatch = content.match(/\{\s*"name"\s*:\s*"([^"]+)"/);
979
981
  if (jsonMatch) {
@@ -1116,7 +1118,8 @@ var WebLLMLanguageModel = class {
1116
1118
  responseFormat,
1117
1119
  seed,
1118
1120
  tools,
1119
- toolChoice
1121
+ toolChoice,
1122
+ providerOptions
1120
1123
  }) {
1121
1124
  const warnings = [];
1122
1125
  const functionTools = (tools ?? []).filter(isFunctionTool).map((tool) => ({
@@ -1183,6 +1186,12 @@ var WebLLMLanguageModel = class {
1183
1186
  top_p: topP,
1184
1187
  seed
1185
1188
  };
1189
+ if (providerOptions?.extra_body) {
1190
+ requestOptions.extra_body = {
1191
+ enable_thinking: providerOptions.extra_body.enable_thinking,
1192
+ enable_latency_breakdown: providerOptions.extra_body.enable_latency_breakdown
1193
+ };
1194
+ }
1186
1195
  if (responseFormat?.type === "json") {
1187
1196
  requestOptions.response_format = {
1188
1197
  type: "json_object",
@@ -1688,16 +1697,213 @@ var WebLLMLanguageModel = class {
1688
1697
  }
1689
1698
  };
1690
1699
 
1700
+ // src/web-llm-embedding-model.ts
1701
+ import {
1702
+ CreateWebWorkerMLCEngine as CreateWebWorkerMLCEngine2,
1703
+ MLCEngine as MLCEngine2
1704
+ } from "@mlc-ai/web-llm";
1705
+ var WebLLMEmbeddingModel = class {
1706
+ constructor(modelId, options = {}) {
1707
+ this.specificationVersion = "v3";
1708
+ this.provider = "web-llm";
1709
+ this.supportsParallelCalls = false;
1710
+ this.isInitialized = false;
1711
+ this.modelId = modelId;
1712
+ this.maxEmbeddingsPerCall = options.maxEmbeddingsPerCall ?? 100;
1713
+ this.config = {
1714
+ provider: this.provider,
1715
+ modelId,
1716
+ options
1717
+ };
1718
+ }
1719
+ /**
1720
+ * Check if the model is initialized and ready to use
1721
+ */
1722
+ get isModelInitialized() {
1723
+ return this.isInitialized;
1724
+ }
1725
+ async getEngine(options, onInitProgress) {
1726
+ const availability = await this.availability();
1727
+ if (availability === "unavailable") {
1728
+ throw new LoadSettingError({
1729
+ message: "WebLLM is not available. This library requires a browser with WebGPU support."
1730
+ });
1731
+ }
1732
+ if (this.engine && this.isInitialized) return this.engine;
1733
+ if (this.initializationPromise) {
1734
+ await this.initializationPromise;
1735
+ if (this.engine) return this.engine;
1736
+ }
1737
+ this.initializationPromise = this._initializeEngine(
1738
+ options,
1739
+ onInitProgress
1740
+ );
1741
+ await this.initializationPromise;
1742
+ if (!this.engine) {
1743
+ throw new LoadSettingError({
1744
+ message: "Engine initialization failed"
1745
+ });
1746
+ }
1747
+ return this.engine;
1748
+ }
1749
+ async _initializeEngine(options, onInitProgress) {
1750
+ try {
1751
+ const engineConfig = {
1752
+ ...this.config.options.engineConfig,
1753
+ ...options,
1754
+ initProgressCallback: onInitProgress || this.config.options.initProgressCallback
1755
+ };
1756
+ if (this.config.options.worker) {
1757
+ this.engine = await CreateWebWorkerMLCEngine2(
1758
+ this.config.options.worker,
1759
+ this.modelId,
1760
+ engineConfig
1761
+ );
1762
+ } else {
1763
+ this.engine = new MLCEngine2(engineConfig);
1764
+ await this.engine.reload(this.modelId);
1765
+ }
1766
+ this.isInitialized = true;
1767
+ } catch (error) {
1768
+ this.engine = void 0;
1769
+ this.isInitialized = false;
1770
+ this.initializationPromise = void 0;
1771
+ throw new LoadSettingError({
1772
+ message: `Failed to initialize WebLLM embedding engine: ${error instanceof Error ? error.message : "Unknown error"}`
1773
+ });
1774
+ }
1775
+ }
1776
+ /**
1777
+ * Check the availability of the WebLLM embedding model
1778
+ * @returns Promise resolving to "unavailable", "available", or "downloadable"
1779
+ */
1780
+ async availability() {
1781
+ if (this.isInitialized) {
1782
+ return "available";
1783
+ }
1784
+ if (this.config.options.worker && isMobile()) {
1785
+ return "downloadable";
1786
+ }
1787
+ const supported = checkWebGPU();
1788
+ return supported ? "downloadable" : "unavailable";
1789
+ }
1790
+ /**
1791
+ * Creates an engine session with download progress monitoring.
1792
+ *
1793
+ * @example
1794
+ * ```typescript
1795
+ * const engine = await model.createSessionWithProgress(
1796
+ * (progress) => {
1797
+ * console.log(`Download progress: ${Math.round(progress.progress * 100)}%`);
1798
+ * }
1799
+ * );
1800
+ * ```
1801
+ *
1802
+ * @param onInitProgress Optional callback receiving progress reports during model download
1803
+ * @returns Promise resolving to a configured WebLLM engine
1804
+ * @throws {LoadSettingError} When WebLLM isn't available or model is unavailable
1805
+ */
1806
+ async createSessionWithProgress(onInitProgress) {
1807
+ return this.getEngine(void 0, onInitProgress);
1808
+ }
1809
+ /**
1810
+ * Embed texts using the WebLLM embedding model
1811
+ */
1812
+ async doEmbed(options) {
1813
+ const { values, abortSignal } = options;
1814
+ if (values.length > this.maxEmbeddingsPerCall) {
1815
+ throw new TooManyEmbeddingValuesForCallError({
1816
+ provider: this.provider,
1817
+ modelId: this.modelId,
1818
+ maxEmbeddingsPerCall: this.maxEmbeddingsPerCall,
1819
+ values
1820
+ });
1821
+ }
1822
+ if (abortSignal?.aborted) {
1823
+ throw new Error("Operation was aborted");
1824
+ }
1825
+ const engine = await this.getEngine();
1826
+ const abortHandler = () => {
1827
+ engine.interruptGenerate();
1828
+ };
1829
+ if (abortSignal) {
1830
+ abortSignal.addEventListener("abort", abortHandler);
1831
+ }
1832
+ try {
1833
+ const response = await engine.embeddings.create({
1834
+ input: values,
1835
+ model: this.modelId,
1836
+ ...abortSignal && !this.config.options.worker && { signal: abortSignal }
1837
+ });
1838
+ const sortedEmbeddings = response.data.sort((a, b) => a.index - b.index).map((e) => e.embedding);
1839
+ return {
1840
+ embeddings: sortedEmbeddings,
1841
+ usage: {
1842
+ tokens: response.usage.total_tokens
1843
+ },
1844
+ providerMetadata: {
1845
+ webllm: {
1846
+ model: response.model,
1847
+ promptTokens: response.usage.prompt_tokens,
1848
+ totalTokens: response.usage.total_tokens,
1849
+ prefillTokensPerSecond: response.usage.extra?.prefill_tokens_per_s
1850
+ }
1851
+ },
1852
+ warnings: []
1853
+ };
1854
+ } catch (error) {
1855
+ throw new Error(
1856
+ `WebLLM embedding failed: ${error instanceof Error ? error.message : "Unknown error"}`
1857
+ );
1858
+ } finally {
1859
+ if (abortSignal) {
1860
+ abortSignal.removeEventListener("abort", abortHandler);
1861
+ }
1862
+ }
1863
+ }
1864
+ };
1865
+
1691
1866
  // src/index.ts
1692
1867
  import { WebWorkerMLCEngineHandler } from "@mlc-ai/web-llm";
1693
1868
 
1694
1869
  // src/web-llm-provider.ts
1695
- function webLLM(modelId, settings) {
1696
- return new WebLLMLanguageModel(modelId, settings);
1870
+ function createWebLLM() {
1871
+ const createLanguageModel = (modelId, settings) => {
1872
+ return new WebLLMLanguageModel(modelId, settings);
1873
+ };
1874
+ const createEmbeddingModel = (modelId, settings) => {
1875
+ return new WebLLMEmbeddingModel(modelId, settings);
1876
+ };
1877
+ const provider = function(modelId, settings) {
1878
+ if (new.target) {
1879
+ throw new Error(
1880
+ "The WebLLM model function cannot be called with the new keyword."
1881
+ );
1882
+ }
1883
+ return createLanguageModel(modelId, settings);
1884
+ };
1885
+ provider.specificationVersion = "v3";
1886
+ provider.languageModel = createLanguageModel;
1887
+ provider.chat = createLanguageModel;
1888
+ provider.embedding = createEmbeddingModel;
1889
+ provider.embeddingModel = createEmbeddingModel;
1890
+ provider.imageModel = (modelId) => {
1891
+ throw new NoSuchModelError({ modelId, modelType: "imageModel" });
1892
+ };
1893
+ provider.speechModel = (modelId) => {
1894
+ throw new NoSuchModelError({ modelId, modelType: "speechModel" });
1895
+ };
1896
+ provider.transcriptionModel = (modelId) => {
1897
+ throw new NoSuchModelError({ modelId, modelType: "transcriptionModel" });
1898
+ };
1899
+ return provider;
1697
1900
  }
1901
+ var webLLM = createWebLLM();
1698
1902
  export {
1903
+ WebLLMEmbeddingModel,
1699
1904
  WebLLMLanguageModel,
1700
1905
  WebWorkerMLCEngineHandler,
1906
+ createWebLLM,
1701
1907
  doesBrowserSupportWebLLM,
1702
1908
  webLLM
1703
1909
  };