llama-cpp-pro 0.2.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.
Files changed (310) hide show
  1. package/CHANGELOG.md +295 -0
  2. package/LICENSE +21 -0
  3. package/LlamaCpp.podspec +33 -0
  4. package/LlamaCppCapacitor.podspec +33 -0
  5. package/Package.swift +29 -0
  6. package/README.md +93 -0
  7. package/android/build.gradle +88 -0
  8. package/android/src/main/AndroidManifest.xml +4 -0
  9. package/android/src/main/CMakeLists-arm64.txt +138 -0
  10. package/android/src/main/CMakeLists-x86_64.txt +141 -0
  11. package/android/src/main/CMakeLists.txt +138 -0
  12. package/android/src/main/java/ai/annadata/plugin/capacitor/LlamaCpp.java +1340 -0
  13. package/android/src/main/java/ai/annadata/plugin/capacitor/LlamaCppPlugin.java +814 -0
  14. package/android/src/main/java/ai/annadata/plugin/capacitor/ModelAdmissionController.java +214 -0
  15. package/android/src/main/jni-chat-session.cpp +261 -0
  16. package/android/src/main/jni-lora.cpp +197 -0
  17. package/android/src/main/jni-multimodal.cpp +167 -0
  18. package/android/src/main/jni-tts.cpp +290 -0
  19. package/android/src/main/jni-utils.h +148 -0
  20. package/android/src/main/jni.cpp +1808 -0
  21. package/android/src/main/jniLibs/arm64-v8a/libllama-cpp-arm64.so +0 -0
  22. package/android/src/main/res/.gitkeep +0 -0
  23. package/build-native.sh +280 -0
  24. package/cmake/desktop-metal-embed.cmake +30 -0
  25. package/cmake/desktop-sources.cmake +100 -0
  26. package/cmake/ggml-backends.cmake +44 -0
  27. package/cpp/LICENSE +21 -0
  28. package/cpp/README.md +15 -0
  29. package/cpp/anyascii.c +22223 -0
  30. package/cpp/anyascii.h +42 -0
  31. package/cpp/cap-completion.cpp +942 -0
  32. package/cpp/cap-completion.h +127 -0
  33. package/cpp/cap-embedding.cpp +193 -0
  34. package/cpp/cap-embedding.h +35 -0
  35. package/cpp/cap-ios-bridge.cpp +1810 -0
  36. package/cpp/cap-ios-bridge.h +61 -0
  37. package/cpp/cap-llama.cpp +412 -0
  38. package/cpp/cap-llama.h +161 -0
  39. package/cpp/cap-mtmd.hpp +602 -0
  40. package/cpp/cap-native-server.cpp +1095 -0
  41. package/cpp/cap-native-server.h +40 -0
  42. package/cpp/cap-tts.cpp +591 -0
  43. package/cpp/cap-tts.h +59 -0
  44. package/cpp/cap-wasm-fs.cpp +156 -0
  45. package/cpp/cap-wasm-jspi.cpp +19 -0
  46. package/cpp/cap-wasm-jspi.h +30 -0
  47. package/cpp/cap-wasm-vfs.cpp +22 -0
  48. package/cpp/chat-parser.cpp +393 -0
  49. package/cpp/chat-parser.h +120 -0
  50. package/cpp/chat.cpp +2315 -0
  51. package/cpp/chat.h +221 -0
  52. package/cpp/common.cpp +1664 -0
  53. package/cpp/common.h +744 -0
  54. package/cpp/ggml-alloc.c +1028 -0
  55. package/cpp/ggml-alloc.h +76 -0
  56. package/cpp/ggml-backend-impl.h +255 -0
  57. package/cpp/ggml-backend-reg.cpp +600 -0
  58. package/cpp/ggml-backend.cpp +2121 -0
  59. package/cpp/ggml-backend.h +354 -0
  60. package/cpp/ggml-common.h +1878 -0
  61. package/cpp/ggml-cpp.h +39 -0
  62. package/cpp/ggml-cpu/amx/amx.cpp +221 -0
  63. package/cpp/ggml-cpu/amx/amx.h +8 -0
  64. package/cpp/ggml-cpu/amx/common.h +91 -0
  65. package/cpp/ggml-cpu/amx/mmq.cpp +2512 -0
  66. package/cpp/ggml-cpu/amx/mmq.h +10 -0
  67. package/cpp/ggml-cpu/arch/arm/cpu-feats.cpp +94 -0
  68. package/cpp/ggml-cpu/arch/arm/quants.c +3650 -0
  69. package/cpp/ggml-cpu/arch/arm/repack.cpp +1891 -0
  70. package/cpp/ggml-cpu/arch/x86/cpu-feats.cpp +327 -0
  71. package/cpp/ggml-cpu/arch/x86/quants.c +3820 -0
  72. package/cpp/ggml-cpu/arch/x86/repack.cpp +6307 -0
  73. package/cpp/ggml-cpu/arch-fallback.h +215 -0
  74. package/cpp/ggml-cpu/binary-ops.cpp +158 -0
  75. package/cpp/ggml-cpu/binary-ops.h +16 -0
  76. package/cpp/ggml-cpu/common.h +73 -0
  77. package/cpp/ggml-cpu/ggml-cpu-impl.h +559 -0
  78. package/cpp/ggml-cpu/ggml-cpu.c +3578 -0
  79. package/cpp/ggml-cpu/ggml-cpu.cpp +672 -0
  80. package/cpp/ggml-cpu/ops.cpp +10587 -0
  81. package/cpp/ggml-cpu/ops.h +114 -0
  82. package/cpp/ggml-cpu/quants.c +1193 -0
  83. package/cpp/ggml-cpu/quants.h +97 -0
  84. package/cpp/ggml-cpu/repack.cpp +1982 -0
  85. package/cpp/ggml-cpu/repack.h +120 -0
  86. package/cpp/ggml-cpu/simd-mappings.h +1184 -0
  87. package/cpp/ggml-cpu/traits.cpp +36 -0
  88. package/cpp/ggml-cpu/traits.h +38 -0
  89. package/cpp/ggml-cpu/unary-ops.cpp +186 -0
  90. package/cpp/ggml-cpu/unary-ops.h +28 -0
  91. package/cpp/ggml-cpu/vec.cpp +348 -0
  92. package/cpp/ggml-cpu/vec.h +1121 -0
  93. package/cpp/ggml-cpu.h +145 -0
  94. package/cpp/ggml-impl.h +622 -0
  95. package/cpp/ggml-metal-impl.h +688 -0
  96. package/cpp/ggml-metal.h +66 -0
  97. package/cpp/ggml-metal.m +6833 -0
  98. package/cpp/ggml-metal.metal +10754 -0
  99. package/cpp/ggml-opt.cpp +1093 -0
  100. package/cpp/ggml-opt.h +256 -0
  101. package/cpp/ggml-quants.c +5324 -0
  102. package/cpp/ggml-quants.h +106 -0
  103. package/cpp/ggml-threading.cpp +12 -0
  104. package/cpp/ggml-threading.h +14 -0
  105. package/cpp/ggml.c +7108 -0
  106. package/cpp/ggml.h +2492 -0
  107. package/cpp/gguf.cpp +1358 -0
  108. package/cpp/gguf.h +202 -0
  109. package/cpp/json-partial.cpp +256 -0
  110. package/cpp/json-partial.h +38 -0
  111. package/cpp/json-schema-to-grammar.cpp +985 -0
  112. package/cpp/json-schema-to-grammar.h +21 -0
  113. package/cpp/llama-adapter.cpp +388 -0
  114. package/cpp/llama-adapter.h +76 -0
  115. package/cpp/llama-arch.cpp +2355 -0
  116. package/cpp/llama-arch.h +499 -0
  117. package/cpp/llama-batch.cpp +875 -0
  118. package/cpp/llama-batch.h +160 -0
  119. package/cpp/llama-chat.cpp +783 -0
  120. package/cpp/llama-chat.h +65 -0
  121. package/cpp/llama-context.cpp +2788 -0
  122. package/cpp/llama-context.h +306 -0
  123. package/cpp/llama-cparams.cpp +5 -0
  124. package/cpp/llama-cparams.h +41 -0
  125. package/cpp/llama-cpp.h +30 -0
  126. package/cpp/llama-grammar.cpp +1229 -0
  127. package/cpp/llama-grammar.h +173 -0
  128. package/cpp/llama-graph.cpp +1891 -0
  129. package/cpp/llama-graph.h +810 -0
  130. package/cpp/llama-hparams.cpp +180 -0
  131. package/cpp/llama-hparams.h +233 -0
  132. package/cpp/llama-impl.cpp +167 -0
  133. package/cpp/llama-impl.h +61 -0
  134. package/cpp/llama-io.cpp +15 -0
  135. package/cpp/llama-io.h +35 -0
  136. package/cpp/llama-kv-cache-iswa.cpp +318 -0
  137. package/cpp/llama-kv-cache-iswa.h +135 -0
  138. package/cpp/llama-kv-cache.cpp +2059 -0
  139. package/cpp/llama-kv-cache.h +374 -0
  140. package/cpp/llama-kv-cells.h +491 -0
  141. package/cpp/llama-memory-hybrid.cpp +258 -0
  142. package/cpp/llama-memory-hybrid.h +137 -0
  143. package/cpp/llama-memory-recurrent.cpp +1146 -0
  144. package/cpp/llama-memory-recurrent.h +179 -0
  145. package/cpp/llama-memory.cpp +59 -0
  146. package/cpp/llama-memory.h +119 -0
  147. package/cpp/llama-mmap.cpp +609 -0
  148. package/cpp/llama-mmap.h +68 -0
  149. package/cpp/llama-model-loader.cpp +1166 -0
  150. package/cpp/llama-model-loader.h +170 -0
  151. package/cpp/llama-model-saver.cpp +282 -0
  152. package/cpp/llama-model-saver.h +37 -0
  153. package/cpp/llama-model.cpp +19061 -0
  154. package/cpp/llama-model.h +491 -0
  155. package/cpp/llama-sampling.cpp +2575 -0
  156. package/cpp/llama-sampling.h +32 -0
  157. package/cpp/llama-vocab.cpp +3792 -0
  158. package/cpp/llama-vocab.h +176 -0
  159. package/cpp/llama.cpp +358 -0
  160. package/cpp/llama.h +1373 -0
  161. package/cpp/log.cpp +428 -0
  162. package/cpp/log.h +103 -0
  163. package/cpp/minja/chat-template.hpp +550 -0
  164. package/cpp/minja/minja.hpp +3009 -0
  165. package/cpp/nlohmann/json.hpp +25526 -0
  166. package/cpp/nlohmann/json_fwd.hpp +187 -0
  167. package/cpp/regex-partial.cpp +204 -0
  168. package/cpp/regex-partial.h +56 -0
  169. package/cpp/sampling.cpp +579 -0
  170. package/cpp/sampling.h +107 -0
  171. package/cpp/tools/mtmd/clip-impl.h +473 -0
  172. package/cpp/tools/mtmd/clip.cpp +4322 -0
  173. package/cpp/tools/mtmd/clip.h +106 -0
  174. package/cpp/tools/mtmd/miniaudio/miniaudio.h +93468 -0
  175. package/cpp/tools/mtmd/mtmd-audio.cpp +769 -0
  176. package/cpp/tools/mtmd/mtmd-audio.h +47 -0
  177. package/cpp/tools/mtmd/mtmd-helper.cpp +460 -0
  178. package/cpp/tools/mtmd/mtmd-helper.h +95 -0
  179. package/cpp/tools/mtmd/mtmd.cpp +1066 -0
  180. package/cpp/tools/mtmd/mtmd.h +302 -0
  181. package/cpp/tools/mtmd/stb/stb_image.h +7988 -0
  182. package/cpp/unicode-data.cpp +7034 -0
  183. package/cpp/unicode-data.h +20 -0
  184. package/cpp/unicode.cpp +1061 -0
  185. package/cpp/unicode.h +68 -0
  186. package/cpp/vendor/cpp-httplib/httplib.cpp +16509 -0
  187. package/cpp/vendor/cpp-httplib/httplib.h +3883 -0
  188. package/desktop/electron-builder.config.cjs +157 -0
  189. package/desktop/entitlements.mac.plist +12 -0
  190. package/desktop/package.json +11 -0
  191. package/desktop/resolve-package-root.cjs +88 -0
  192. package/desktop/src/main/backend-selector.cjs +148 -0
  193. package/desktop/src/main/gpu-probe.cjs +142 -0
  194. package/desktop/src/main/index.cjs +58 -0
  195. package/desktop/src/main/ipc-handlers.cjs +212 -0
  196. package/desktop/src/main/model-store.cjs +50 -0
  197. package/desktop/src/main/preload.cjs +39 -0
  198. package/desktop/src/main/sidecar-client.cjs +76 -0
  199. package/desktop/src/main/sidecar-manager.cjs +364 -0
  200. package/dist/docs.json +14357 -0
  201. package/dist/esm/definitions.d.ts +731 -0
  202. package/dist/esm/definitions.js +2 -0
  203. package/dist/esm/definitions.js.map +1 -0
  204. package/dist/esm/desktop.d.ts +37 -0
  205. package/dist/esm/desktop.js +133 -0
  206. package/dist/esm/desktop.js.map +1 -0
  207. package/dist/esm/index.d.ts +200 -0
  208. package/dist/esm/index.js +612 -0
  209. package/dist/esm/index.js.map +1 -0
  210. package/dist/esm/isomorphic/desktop.runtime.d.ts +37 -0
  211. package/dist/esm/isomorphic/desktop.runtime.js +36 -0
  212. package/dist/esm/isomorphic/desktop.runtime.js.map +1 -0
  213. package/dist/esm/isomorphic/errors.d.ts +6 -0
  214. package/dist/esm/isomorphic/errors.js +9 -0
  215. package/dist/esm/isomorphic/errors.js.map +1 -0
  216. package/dist/esm/isomorphic/model.admission.d.ts +17 -0
  217. package/dist/esm/isomorphic/model.admission.js +27 -0
  218. package/dist/esm/isomorphic/model.admission.js.map +1 -0
  219. package/dist/esm/isomorphic/model.scheduler.d.ts +31 -0
  220. package/dist/esm/isomorphic/model.scheduler.js +95 -0
  221. package/dist/esm/isomorphic/model.scheduler.js.map +1 -0
  222. package/dist/esm/isomorphic/provider.desktop.d.ts +40 -0
  223. package/dist/esm/isomorphic/provider.desktop.js +411 -0
  224. package/dist/esm/isomorphic/provider.desktop.js.map +1 -0
  225. package/dist/esm/isomorphic/provider.factory.d.ts +2 -0
  226. package/dist/esm/isomorphic/provider.factory.js +16 -0
  227. package/dist/esm/isomorphic/provider.factory.js.map +1 -0
  228. package/dist/esm/isomorphic/provider.interface.d.ts +76 -0
  229. package/dist/esm/isomorphic/provider.interface.js +2 -0
  230. package/dist/esm/isomorphic/provider.interface.js.map +1 -0
  231. package/dist/esm/isomorphic/provider.native.d.ts +18 -0
  232. package/dist/esm/isomorphic/provider.native.js +173 -0
  233. package/dist/esm/isomorphic/provider.native.js.map +1 -0
  234. package/dist/esm/isomorphic/provider.web.d.ts +88 -0
  235. package/dist/esm/isomorphic/provider.web.js +573 -0
  236. package/dist/esm/isomorphic/provider.web.js.map +1 -0
  237. package/dist/esm/isomorphic/sidecar-sse.d.ts +14 -0
  238. package/dist/esm/isomorphic/sidecar-sse.js +76 -0
  239. package/dist/esm/isomorphic/sidecar-sse.js.map +1 -0
  240. package/dist/esm/isomorphic/wasmMemoryCalibration.d.ts +26 -0
  241. package/dist/esm/isomorphic/wasmMemoryCalibration.js +60 -0
  242. package/dist/esm/isomorphic/wasmMemoryCalibration.js.map +1 -0
  243. package/dist/esm/isomorphic/wasmMemoryPolicy.d.ts +55 -0
  244. package/dist/esm/isomorphic/wasmMemoryPolicy.js +93 -0
  245. package/dist/esm/isomorphic/wasmMemoryPolicy.js.map +1 -0
  246. package/dist/esm/storage/manifest.d.ts +13 -0
  247. package/dist/esm/storage/manifest.js +87 -0
  248. package/dist/esm/storage/manifest.js.map +1 -0
  249. package/dist/esm/storage/opfs.store.d.ts +31 -0
  250. package/dist/esm/storage/opfs.store.js +241 -0
  251. package/dist/esm/storage/opfs.store.js.map +1 -0
  252. package/dist/esm/web.d.ts +206 -0
  253. package/dist/esm/web.js +521 -0
  254. package/dist/esm/web.js.map +1 -0
  255. package/dist/esm/workers/async-file.d.ts +13 -0
  256. package/dist/esm/workers/async-file.js +12 -0
  257. package/dist/esm/workers/async-file.js.map +1 -0
  258. package/dist/esm/workers/heapfs.d.ts +55 -0
  259. package/dist/esm/workers/heapfs.js +115 -0
  260. package/dist/esm/workers/heapfs.js.map +1 -0
  261. package/dist/esm/workers/wasm.engine.d.ts +86 -0
  262. package/dist/esm/workers/wasm.engine.js +504 -0
  263. package/dist/esm/workers/wasm.engine.js.map +1 -0
  264. package/dist/esm/workers/worker.protocol.d.ts +160 -0
  265. package/dist/esm/workers/worker.protocol.js +2 -0
  266. package/dist/esm/workers/worker.protocol.js.map +1 -0
  267. package/dist/plugin.cjs +3179 -0
  268. package/dist/plugin.cjs.map +1 -0
  269. package/dist/plugin.js +3181 -0
  270. package/dist/plugin.js.map +1 -0
  271. package/dist/wasm/llama_engine.d.ts +74 -0
  272. package/dist/wasm/llama_engine.js +1829 -0
  273. package/dist/wasm/llama_engine.wasm +0 -0
  274. package/dist/wasm/llama_engine_emscripten.mjs +2 -0
  275. package/dist/wasm/package.json +16 -0
  276. package/dist/workers/llm.worker.js +1226 -0
  277. package/dist/workers/llm.worker.js.map +7 -0
  278. package/extraResources/llama-wasm/llama_engine.d.ts +74 -0
  279. package/extraResources/llama-wasm/llama_engine.js +1829 -0
  280. package/extraResources/llama-wasm/llama_engine.wasm +0 -0
  281. package/extraResources/llama-wasm/llama_engine_emscripten.mjs +2 -0
  282. package/extraResources/llama-wasm/package.json +16 -0
  283. package/extraResources/sidecar/README.md +11 -0
  284. package/extraResources/sidecar/darwin-arm64 +0 -0
  285. package/extraResources/sidecar/darwin-x64 +0 -0
  286. package/ios/CMakeLists-arm64.txt +161 -0
  287. package/ios/CMakeLists-x86_64.txt +188 -0
  288. package/ios/CMakeLists.txt +161 -0
  289. package/ios/Frameworks/llama-cpp.framework/Info.plist +28 -0
  290. package/ios/Frameworks/llama-cpp.framework/llama-cpp +0 -0
  291. package/ios/Sources/LlamaCppCapacitor/LlamaCpp.swift +1365 -0
  292. package/ios/Sources/LlamaCppCapacitor/LlamaCppPlugin.swift +694 -0
  293. package/ios/Sources/LlamaCppCapacitor/LlamaNativeBridge.swift +349 -0
  294. package/ios/Sources/LlamaCppCapacitor/ModelAdmissionController.swift +177 -0
  295. package/ios/embed-metal-shaders.sh +24 -0
  296. package/ios/metal-embed.cmake +29 -0
  297. package/package.json +281 -0
  298. package/scripts/build-js-preserve-wasm.cjs +53 -0
  299. package/scripts/build-sidecar-linux.sh +6 -0
  300. package/scripts/build-sidecar-win.bat +19 -0
  301. package/scripts/build-sidecar.sh +184 -0
  302. package/scripts/embed-llama-ios-app-framework.sh +63 -0
  303. package/scripts/ensure-desktop-sidecar-bundle.cjs +103 -0
  304. package/scripts/ensure-llama-ios-xcframework.sh +108 -0
  305. package/scripts/fix-esm-extensions.cjs +45 -0
  306. package/scripts/prepare-js-dist.cjs +28 -0
  307. package/scripts/stage-desktop-resources.cjs +116 -0
  308. package/sidecar/CMakeLists.txt +192 -0
  309. package/sidecar/cap-sidecar-main.cpp +68 -0
  310. package/types/llama-cpp-pro.d.ts +441 -0
@@ -0,0 +1,241 @@
1
+ import { LlmError } from '../isomorphic/errors';
2
+ import { getManifestEntry, listManifestEntries, removeManifestEntry, upsertManifestEntry, } from './manifest';
3
+ const MODELS_DIR = 'models';
4
+ const getStorageApi = () => {
5
+ var _a;
6
+ const storageApi = (_a = globalThis === null || globalThis === void 0 ? void 0 : globalThis.navigator) === null || _a === void 0 ? void 0 : _a.storage;
7
+ if (!storageApi || typeof storageApi.getDirectory !== 'function') {
8
+ throw new LlmError('STORAGE_UNAVAILABLE', 'OPFS is not available in this runtime. navigator.storage.getDirectory is missing.');
9
+ }
10
+ return storageApi;
11
+ };
12
+ const getRootDirectory = async () => {
13
+ const storageApi = getStorageApi();
14
+ try {
15
+ return await storageApi.getDirectory();
16
+ }
17
+ catch (error) {
18
+ throw new LlmError('STORAGE_IO_FAILED', 'Failed to access OPFS root directory.', {
19
+ cause: String(error),
20
+ });
21
+ }
22
+ };
23
+ const sanitizeModelId = (modelId) => modelId.replace(/[^a-zA-Z0-9._-]/g, '_');
24
+ const pathForModelId = (modelId) => `${MODELS_DIR}/${sanitizeModelId(modelId)}.gguf`;
25
+ const ensureParentDirAndFileHandle = async (path, create = true) => {
26
+ const root = await getRootDirectory();
27
+ const parts = path.split('/').filter(Boolean);
28
+ const fileName = parts.pop();
29
+ if (!fileName) {
30
+ throw new LlmError('STORAGE_IO_FAILED', `Invalid OPFS path '${path}'.`);
31
+ }
32
+ let current = root;
33
+ for (const dir of parts) {
34
+ current = await current.getDirectoryHandle(dir, { create: true });
35
+ }
36
+ return current.getFileHandle(fileName, { create });
37
+ };
38
+ const writeStreamToFile = async (res, fileHandle, onProgress, signal) => {
39
+ var _a;
40
+ const writable = await fileHandle.createWritable();
41
+ const total = Number((_a = res.headers.get('content-length')) !== null && _a !== void 0 ? _a : 0);
42
+ let written = 0;
43
+ try {
44
+ if (!res.body) {
45
+ const buf = await res.arrayBuffer();
46
+ await writable.write(buf);
47
+ written += buf.byteLength;
48
+ onProgress === null || onProgress === void 0 ? void 0 : onProgress(written, total || written);
49
+ return written;
50
+ }
51
+ const reader = res.body.getReader();
52
+ while (true) {
53
+ if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
54
+ reader.cancel();
55
+ throw new LlmError('MODEL_DOWNLOAD_FAILED', 'Download aborted by caller.');
56
+ }
57
+ const { value, done } = await reader.read();
58
+ if (done)
59
+ break;
60
+ if (value) {
61
+ await writable.write(value);
62
+ written += value.byteLength;
63
+ onProgress === null || onProgress === void 0 ? void 0 : onProgress(written, total || written);
64
+ }
65
+ }
66
+ return written;
67
+ }
68
+ finally {
69
+ await writable.close();
70
+ }
71
+ };
72
+ export async function ensureModelInOpfs(modelId, modelUrl, onProgress, signal) {
73
+ if (!modelId) {
74
+ throw new LlmError('INVALID_REQUEST', 'modelId is required for OPFS storage.');
75
+ }
76
+ if (!modelUrl) {
77
+ throw new LlmError('INVALID_REQUEST', 'modelUrl is required for OPFS storage.');
78
+ }
79
+ const existing = await getManifestEntry(modelId);
80
+ if (existing) {
81
+ await upsertManifestEntry(Object.assign(Object.assign({}, existing), { lastUsedAt: Date.now() }));
82
+ return Object.assign(Object.assign({}, existing), { lastUsedAt: Date.now() });
83
+ }
84
+ let res;
85
+ try {
86
+ res = await fetch(modelUrl, signal ? { signal } : undefined);
87
+ }
88
+ catch (error) {
89
+ const isAbort = error instanceof Error && error.name === 'AbortError';
90
+ throw new LlmError('MODEL_DOWNLOAD_FAILED', isAbort
91
+ ? `Download of model '${modelId}' was cancelled.`
92
+ : `Failed to download model '${modelId}'.`, { modelId, modelUrl, cause: String(error) });
93
+ }
94
+ if (!res.ok) {
95
+ throw new LlmError('MODEL_DOWNLOAD_FAILED', `Failed to download model '${modelId}': HTTP ${res.status}`, {
96
+ modelId,
97
+ modelUrl,
98
+ status: res.status,
99
+ });
100
+ }
101
+ const path = pathForModelId(modelId);
102
+ let sizeBytes = 0;
103
+ try {
104
+ const fileHandle = await ensureParentDirAndFileHandle(path, true);
105
+ sizeBytes = await writeStreamToFile(res, fileHandle, onProgress, signal);
106
+ }
107
+ catch (error) {
108
+ throw new LlmError('STORAGE_IO_FAILED', `Failed to persist model '${modelId}' in OPFS.`, {
109
+ modelId,
110
+ path,
111
+ cause: String(error),
112
+ });
113
+ }
114
+ const now = Date.now();
115
+ const entry = {
116
+ modelId,
117
+ path,
118
+ sizeBytes,
119
+ sourceUrl: modelUrl,
120
+ createdAt: now,
121
+ lastUsedAt: now,
122
+ };
123
+ await upsertManifestEntry(entry);
124
+ return entry;
125
+ }
126
+ /**
127
+ * Choice 3 — primary web model load path.
128
+ * Opens an OPFS FileSystemSyncAccessHandle in the worker and reads the
129
+ * model in fixed-size chunks (default 4MB). Chunks are streamed into WASM
130
+ * MEMFS; the full GGUF is never materialised as a single JS ArrayBuffer.
131
+ *
132
+ * Worker-only: createSyncAccessHandle is not available on the main thread.
133
+ */
134
+ export const OPFS_MODEL_CHUNK_BYTES = 4 * 1024 * 1024;
135
+ export async function openOpfsModelSyncReader(modelId) {
136
+ const entry = await getManifestEntry(modelId);
137
+ if (!entry) {
138
+ throw new LlmError('MODEL_NOT_LOADED', `Model '${modelId}' is not present in OPFS manifest.`);
139
+ }
140
+ const fileHandle = await ensureParentDirAndFileHandle(entry.path, false);
141
+ if (typeof fileHandle.createSyncAccessHandle !== 'function') {
142
+ throw new LlmError('STORAGE_UNAVAILABLE', 'OPFS sync access handles are not available in this browser/worker context.', { modelId });
143
+ }
144
+ let accessHandle;
145
+ try {
146
+ accessHandle = await fileHandle.createSyncAccessHandle();
147
+ }
148
+ catch (error) {
149
+ throw new LlmError('STORAGE_IO_FAILED', `Failed to open OPFS sync handle for '${modelId}'.`, {
150
+ modelId,
151
+ path: entry.path,
152
+ cause: String(error),
153
+ });
154
+ }
155
+ const sizeBytes = accessHandle.getSize();
156
+ await upsertManifestEntry(Object.assign(Object.assign({}, entry), { lastUsedAt: Date.now() }));
157
+ return {
158
+ sizeBytes,
159
+ readChunk(offset, length = OPFS_MODEL_CHUNK_BYTES) {
160
+ const toRead = Math.min(length, sizeBytes - offset);
161
+ if (toRead <= 0) {
162
+ return new Uint8Array(0);
163
+ }
164
+ const buf = new Uint8Array(toRead);
165
+ const bytesRead = accessHandle.read(buf, { at: offset });
166
+ return buf.subarray(0, bytesRead);
167
+ },
168
+ close() {
169
+ accessHandle.close();
170
+ },
171
+ };
172
+ }
173
+ /**
174
+ * Read the model from OPFS as an ArrayBuffer (fallback when sync handles
175
+ * are unavailable). Prefer openOpfsModelSyncReader in workers.
176
+ */
177
+ export async function readModelBufferFromOpfs(modelId) {
178
+ const file = await readModelFromOpfs(modelId);
179
+ const buffer = await file.arrayBuffer();
180
+ return { buffer, sizeBytes: file.size };
181
+ }
182
+ export async function readModelFromOpfs(modelId) {
183
+ const entry = await getManifestEntry(modelId);
184
+ if (!entry) {
185
+ throw new LlmError('MODEL_NOT_LOADED', `Model '${modelId}' is not present in OPFS manifest.`);
186
+ }
187
+ try {
188
+ const fileHandle = await ensureParentDirAndFileHandle(entry.path, false);
189
+ const file = await fileHandle.getFile();
190
+ await upsertManifestEntry(Object.assign(Object.assign({}, entry), { lastUsedAt: Date.now() }));
191
+ return file;
192
+ }
193
+ catch (error) {
194
+ throw new LlmError('STORAGE_IO_FAILED', `Failed to read model '${modelId}' from OPFS.`, {
195
+ modelId,
196
+ path: entry.path,
197
+ cause: String(error),
198
+ });
199
+ }
200
+ }
201
+ export async function removeModelFromOpfs(modelId) {
202
+ const entry = await getManifestEntry(modelId);
203
+ if (!entry)
204
+ return;
205
+ const root = await getRootDirectory();
206
+ const parts = entry.path.split('/').filter(Boolean);
207
+ const fileName = parts.pop();
208
+ if (!fileName) {
209
+ await removeManifestEntry(modelId);
210
+ return;
211
+ }
212
+ try {
213
+ let current = root;
214
+ for (const dir of parts) {
215
+ current = await current.getDirectoryHandle(dir, { create: false });
216
+ }
217
+ await current.removeEntry(fileName);
218
+ }
219
+ catch (error) {
220
+ // Keep manifest cleanup deterministic even if file was already gone.
221
+ if (!(error instanceof Error) || !/not found/i.test(error.message)) {
222
+ throw new LlmError('STORAGE_IO_FAILED', `Failed to remove model '${modelId}' from OPFS.`, {
223
+ modelId,
224
+ path: entry.path,
225
+ cause: String(error),
226
+ });
227
+ }
228
+ }
229
+ finally {
230
+ await removeManifestEntry(modelId);
231
+ }
232
+ }
233
+ export async function getOpfsUsage() {
234
+ var _a, _b, _c;
235
+ const entries = await listManifestEntries();
236
+ const usedBytes = entries.reduce((sum, e) => sum + (e.sizeBytes || 0), 0);
237
+ const estimate = await ((_c = (_b = (_a = globalThis === null || globalThis === void 0 ? void 0 : globalThis.navigator) === null || _a === void 0 ? void 0 : _a.storage) === null || _b === void 0 ? void 0 : _b.estimate) === null || _c === void 0 ? void 0 : _c.call(_b));
238
+ const quotaBytes = typeof (estimate === null || estimate === void 0 ? void 0 : estimate.quota) === 'number' ? estimate.quota : undefined;
239
+ return { usedBytes, quotaBytes };
240
+ }
241
+ //# sourceMappingURL=opfs.store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opfs.store.js","sourceRoot":"","sources":["../../../src/storage/opfs.store.ts"],"names":[],"mappings":"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","sourcesContent":["import { LlmError } from '../isomorphic/errors';\nimport {\n getManifestEntry,\n listManifestEntries,\n type ModelManifestEntry,\n removeManifestEntry,\n upsertManifestEntry,\n} from './manifest';\n\nconst MODELS_DIR = 'models';\n\nconst getStorageApi = (): any => {\n const storageApi = (globalThis as any)?.navigator?.storage;\n if (!storageApi || typeof storageApi.getDirectory !== 'function') {\n throw new LlmError(\n 'STORAGE_UNAVAILABLE',\n 'OPFS is not available in this runtime. navigator.storage.getDirectory is missing.',\n );\n }\n return storageApi;\n};\n\nconst getRootDirectory = async (): Promise<any> => {\n const storageApi = getStorageApi();\n try {\n return await storageApi.getDirectory();\n } catch (error) {\n throw new LlmError('STORAGE_IO_FAILED', 'Failed to access OPFS root directory.', {\n cause: String(error),\n });\n }\n};\n\nconst sanitizeModelId = (modelId: string): string =>\n modelId.replace(/[^a-zA-Z0-9._-]/g, '_');\n\nconst pathForModelId = (modelId: string): string =>\n `${MODELS_DIR}/${sanitizeModelId(modelId)}.gguf`;\n\nconst ensureParentDirAndFileHandle = async (path: string, create = true): Promise<any> => {\n const root = await getRootDirectory();\n const parts = path.split('/').filter(Boolean);\n const fileName = parts.pop();\n if (!fileName) {\n throw new LlmError('STORAGE_IO_FAILED', `Invalid OPFS path '${path}'.`);\n }\n let current = root;\n for (const dir of parts) {\n current = await current.getDirectoryHandle(dir, { create: true });\n }\n return current.getFileHandle(fileName, { create });\n};\n\nconst writeStreamToFile = async (\n res: Response,\n fileHandle: any,\n onProgress?: (downloaded: number, total: number) => void,\n signal?: AbortSignal,\n): Promise<number> => {\n const writable = await fileHandle.createWritable();\n const total = Number(res.headers.get('content-length') ?? 0);\n let written = 0;\n try {\n if (!res.body) {\n const buf = await res.arrayBuffer();\n await writable.write(buf);\n written += buf.byteLength;\n onProgress?.(written, total || written);\n return written;\n }\n\n const reader = res.body.getReader();\n while (true) {\n if (signal?.aborted) {\n reader.cancel();\n throw new LlmError('MODEL_DOWNLOAD_FAILED', 'Download aborted by caller.');\n }\n const { value, done } = await reader.read();\n if (done) break;\n if (value) {\n await writable.write(value);\n written += value.byteLength;\n onProgress?.(written, total || written);\n }\n }\n return written;\n } finally {\n await writable.close();\n }\n};\n\nexport async function ensureModelInOpfs(\n modelId: string,\n modelUrl: string,\n onProgress?: (downloaded: number, total: number) => void,\n signal?: AbortSignal,\n): Promise<ModelManifestEntry> {\n if (!modelId) {\n throw new LlmError('INVALID_REQUEST', 'modelId is required for OPFS storage.');\n }\n if (!modelUrl) {\n throw new LlmError('INVALID_REQUEST', 'modelUrl is required for OPFS storage.');\n }\n\n const existing = await getManifestEntry(modelId);\n if (existing) {\n await upsertManifestEntry({ ...existing, lastUsedAt: Date.now() });\n return { ...existing, lastUsedAt: Date.now() };\n }\n\n let res: Response;\n try {\n res = await fetch(modelUrl, signal ? { signal } : undefined);\n } catch (error) {\n const isAbort = error instanceof Error && error.name === 'AbortError';\n throw new LlmError(\n 'MODEL_DOWNLOAD_FAILED',\n isAbort\n ? `Download of model '${modelId}' was cancelled.`\n : `Failed to download model '${modelId}'.`,\n { modelId, modelUrl, cause: String(error) },\n );\n }\n if (!res.ok) {\n throw new LlmError('MODEL_DOWNLOAD_FAILED', `Failed to download model '${modelId}': HTTP ${res.status}`, {\n modelId,\n modelUrl,\n status: res.status,\n });\n }\n\n const path = pathForModelId(modelId);\n let sizeBytes = 0;\n try {\n const fileHandle = await ensureParentDirAndFileHandle(path, true);\n sizeBytes = await writeStreamToFile(res, fileHandle, onProgress, signal);\n } catch (error) {\n throw new LlmError('STORAGE_IO_FAILED', `Failed to persist model '${modelId}' in OPFS.`, {\n modelId,\n path,\n cause: String(error),\n });\n }\n\n const now = Date.now();\n const entry: ModelManifestEntry = {\n modelId,\n path,\n sizeBytes,\n sourceUrl: modelUrl,\n createdAt: now,\n lastUsedAt: now,\n };\n await upsertManifestEntry(entry);\n return entry;\n}\n\n/**\n * Choice 3 — primary web model load path.\n * Opens an OPFS FileSystemSyncAccessHandle in the worker and reads the\n * model in fixed-size chunks (default 4MB). Chunks are streamed into WASM\n * MEMFS; the full GGUF is never materialised as a single JS ArrayBuffer.\n *\n * Worker-only: createSyncAccessHandle is not available on the main thread.\n */\nexport const OPFS_MODEL_CHUNK_BYTES = 4 * 1024 * 1024;\n\nexport interface OpfsModelSyncReader {\n readonly sizeBytes: number;\n readChunk(offset: number, length?: number): Uint8Array;\n close(): void;\n}\n\nexport async function openOpfsModelSyncReader(modelId: string): Promise<OpfsModelSyncReader> {\n const entry = await getManifestEntry(modelId);\n if (!entry) {\n throw new LlmError('MODEL_NOT_LOADED', `Model '${modelId}' is not present in OPFS manifest.`);\n }\n\n const fileHandle = await ensureParentDirAndFileHandle(entry.path, false);\n if (typeof fileHandle.createSyncAccessHandle !== 'function') {\n throw new LlmError(\n 'STORAGE_UNAVAILABLE',\n 'OPFS sync access handles are not available in this browser/worker context.',\n { modelId },\n );\n }\n\n let accessHandle: {\n getSize(): number;\n read(buffer: Uint8Array, options: { at: number }): number;\n close(): void;\n };\n try {\n accessHandle = await fileHandle.createSyncAccessHandle();\n } catch (error) {\n throw new LlmError('STORAGE_IO_FAILED', `Failed to open OPFS sync handle for '${modelId}'.`, {\n modelId,\n path: entry.path,\n cause: String(error),\n });\n }\n\n const sizeBytes = accessHandle.getSize();\n await upsertManifestEntry({ ...entry, lastUsedAt: Date.now() });\n\n return {\n sizeBytes,\n readChunk(offset: number, length = OPFS_MODEL_CHUNK_BYTES) {\n const toRead = Math.min(length, sizeBytes - offset);\n if (toRead <= 0) {\n return new Uint8Array(0);\n }\n const buf = new Uint8Array(toRead);\n const bytesRead = accessHandle.read(buf, { at: offset });\n return buf.subarray(0, bytesRead);\n },\n close() {\n accessHandle.close();\n },\n };\n}\n\n/**\n * Read the model from OPFS as an ArrayBuffer (fallback when sync handles\n * are unavailable). Prefer openOpfsModelSyncReader in workers.\n */\nexport async function readModelBufferFromOpfs(modelId: string): Promise<{ buffer: ArrayBuffer; sizeBytes: number }> {\n const file = await readModelFromOpfs(modelId);\n const buffer = await file.arrayBuffer();\n return { buffer, sizeBytes: file.size };\n}\n\nexport async function readModelFromOpfs(modelId: string): Promise<File> {\n const entry = await getManifestEntry(modelId);\n if (!entry) {\n throw new LlmError('MODEL_NOT_LOADED', `Model '${modelId}' is not present in OPFS manifest.`);\n }\n try {\n const fileHandle = await ensureParentDirAndFileHandle(entry.path, false);\n const file = await fileHandle.getFile();\n await upsertManifestEntry({ ...entry, lastUsedAt: Date.now() });\n return file;\n } catch (error) {\n throw new LlmError('STORAGE_IO_FAILED', `Failed to read model '${modelId}' from OPFS.`, {\n modelId,\n path: entry.path,\n cause: String(error),\n });\n }\n}\n\nexport async function removeModelFromOpfs(modelId: string): Promise<void> {\n const entry = await getManifestEntry(modelId);\n if (!entry) return;\n\n const root = await getRootDirectory();\n const parts = entry.path.split('/').filter(Boolean);\n const fileName = parts.pop();\n if (!fileName) {\n await removeManifestEntry(modelId);\n return;\n }\n\n try {\n let current = root;\n for (const dir of parts) {\n current = await current.getDirectoryHandle(dir, { create: false });\n }\n await current.removeEntry(fileName);\n } catch (error) {\n // Keep manifest cleanup deterministic even if file was already gone.\n if (!(error instanceof Error) || !/not found/i.test(error.message)) {\n throw new LlmError('STORAGE_IO_FAILED', `Failed to remove model '${modelId}' from OPFS.`, {\n modelId,\n path: entry.path,\n cause: String(error),\n });\n }\n } finally {\n await removeManifestEntry(modelId);\n }\n}\n\nexport async function getOpfsUsage(): Promise<{ usedBytes: number; quotaBytes?: number }> {\n const entries = await listManifestEntries();\n const usedBytes = entries.reduce((sum, e) => sum + (e.sizeBytes || 0), 0);\n const estimate = await (globalThis as any)?.navigator?.storage?.estimate?.();\n const quotaBytes = typeof estimate?.quota === 'number' ? estimate.quota : undefined;\n return { usedBytes, quotaBytes };\n}\n\n"]}
@@ -0,0 +1,206 @@
1
+ import type { LlamaCppPlugin, NativeLlamaContext, NativeCompletionResult, NativeTokenizeResult } from './definitions';
2
+ import { WebProvider } from './isomorphic/provider.web';
3
+ export declare class LlamaCppWeb implements LlamaCppPlugin {
4
+ protected provider: WebProvider;
5
+ protected contextToModel: Map<number, string>;
6
+ protected listeners: Map<string, Set<(data: unknown) => void>>;
7
+ protected emitListener(eventName: string, data: unknown): void;
8
+ protected hasListeners(eventName: string): boolean;
9
+ toggleNativeLog(): Promise<void>;
10
+ setContextLimit(_opts?: {
11
+ limit: number;
12
+ }): Promise<void>;
13
+ modelInfo({ path }: {
14
+ path: string;
15
+ skip?: string[];
16
+ }): Promise<Object>;
17
+ initContext({ contextId, params, }: {
18
+ contextId: number;
19
+ params: any;
20
+ }): Promise<NativeLlamaContext>;
21
+ releaseContext({ contextId }: {
22
+ contextId: number;
23
+ }): Promise<void>;
24
+ releaseAllContexts(): Promise<void>;
25
+ getFormattedChat({ contextId, messages, chatTemplate, params, }: {
26
+ contextId: number;
27
+ messages: string;
28
+ chatTemplate?: string;
29
+ params?: any;
30
+ }): Promise<any>;
31
+ completion({ contextId, params, }: {
32
+ contextId: number;
33
+ params: any;
34
+ }): Promise<NativeCompletionResult>;
35
+ chat({ contextId, messages, system, chatTemplate, params }: {
36
+ contextId: number;
37
+ messages: Array<{
38
+ role: string;
39
+ content: string;
40
+ }>;
41
+ system?: string;
42
+ chatTemplate?: string;
43
+ params?: any;
44
+ }): Promise<NativeCompletionResult>;
45
+ chatWithSystem({ contextId, system, message, params }: {
46
+ contextId: number;
47
+ system: string;
48
+ message: string;
49
+ params?: any;
50
+ }): Promise<NativeCompletionResult>;
51
+ generateText({ contextId, prompt, params }: {
52
+ contextId: number;
53
+ prompt: string;
54
+ params?: any;
55
+ }): Promise<NativeCompletionResult>;
56
+ stopCompletion(): Promise<void>;
57
+ loadSession({ contextId, filepath, }: {
58
+ contextId: number;
59
+ filepath: string;
60
+ }): Promise<{
61
+ tokens_loaded: number;
62
+ prompt: string;
63
+ }>;
64
+ saveSession({ contextId, filepath, size, }: {
65
+ contextId: number;
66
+ filepath: string;
67
+ size: number;
68
+ }): Promise<number>;
69
+ tokenize({ contextId, text, }: {
70
+ contextId: number;
71
+ text: string;
72
+ imagePaths?: string[];
73
+ }): Promise<NativeTokenizeResult>;
74
+ detokenize({ contextId, tokens, }: {
75
+ contextId: number;
76
+ tokens: number[];
77
+ [key: string]: unknown;
78
+ }): Promise<string>;
79
+ embedding({ contextId, text }: {
80
+ contextId: number;
81
+ text: string;
82
+ params: any;
83
+ }): Promise<any>;
84
+ rerank({ contextId, query, documents, }: {
85
+ contextId: number;
86
+ query: string;
87
+ documents: string[];
88
+ params?: Record<string, unknown>;
89
+ }): Promise<Array<{
90
+ score: number;
91
+ index: number;
92
+ }>>;
93
+ bench({ contextId, pp, tg, pl, nr, }: {
94
+ contextId: number;
95
+ pp: number;
96
+ tg: number;
97
+ pl: number;
98
+ nr: number;
99
+ }): Promise<string>;
100
+ applyLoraAdapters({ contextId, loraAdapters, }: {
101
+ contextId: number;
102
+ loraAdapters: Array<{
103
+ path: string;
104
+ scaled?: number;
105
+ }>;
106
+ }): Promise<void>;
107
+ removeLoraAdapters({ contextId }: {
108
+ contextId: number;
109
+ }): Promise<void>;
110
+ getLoadedLoraAdapters({ contextId, }: {
111
+ contextId: number;
112
+ }): Promise<Array<{
113
+ path: string;
114
+ scaled?: number;
115
+ }>>;
116
+ initMultimodal({ contextId, params, }: {
117
+ contextId: number;
118
+ params: {
119
+ path: string;
120
+ use_gpu?: boolean;
121
+ };
122
+ }): Promise<boolean>;
123
+ isMultimodalEnabled({ contextId }: {
124
+ contextId: number;
125
+ }): Promise<boolean>;
126
+ getMultimodalSupport({ contextId }: {
127
+ contextId: number;
128
+ }): Promise<{
129
+ vision: boolean;
130
+ audio: boolean;
131
+ }>;
132
+ releaseMultimodal({ contextId }: {
133
+ contextId: number;
134
+ }): Promise<void>;
135
+ initVocoder({ contextId, params, }: {
136
+ contextId: number;
137
+ params: {
138
+ path: string;
139
+ n_batch?: number;
140
+ };
141
+ }): Promise<boolean>;
142
+ isVocoderEnabled({ contextId }: {
143
+ contextId: number;
144
+ }): Promise<boolean>;
145
+ getFormattedAudioCompletion({ contextId, speakerJsonStr, textToSpeak, }: {
146
+ contextId: number;
147
+ speakerJsonStr: string;
148
+ textToSpeak: string;
149
+ }): Promise<{
150
+ prompt: string;
151
+ grammar?: string;
152
+ }>;
153
+ getAudioCompletionGuideTokens({ contextId, textToSpeak, }: {
154
+ contextId: number;
155
+ textToSpeak: string;
156
+ }): Promise<number[]>;
157
+ decodeAudioTokens({ contextId, tokens, }: {
158
+ contextId: number;
159
+ tokens: number[];
160
+ }): Promise<number[]>;
161
+ releaseVocoder({ contextId }: {
162
+ contextId: number;
163
+ }): Promise<void>;
164
+ downloadModel({ url, filename }: {
165
+ url: string;
166
+ filename: string;
167
+ }): Promise<string>;
168
+ getDownloadProgress({ url }: {
169
+ url: string;
170
+ }): Promise<{
171
+ progress: number;
172
+ completed: boolean;
173
+ failed: boolean;
174
+ errorMessage?: string;
175
+ localPath?: string;
176
+ downloadedBytes: number;
177
+ totalBytes: number;
178
+ }>;
179
+ cancelDownload({ url }: {
180
+ url: string;
181
+ }): Promise<boolean>;
182
+ getAvailableModels(): Promise<Array<{
183
+ name: string;
184
+ path: string;
185
+ size: number;
186
+ }>>;
187
+ convertJsonSchemaToGrammar({ schema, }: {
188
+ schema: string;
189
+ [key: string]: unknown;
190
+ }): Promise<string>;
191
+ startNativeLlamaServer(_options?: {
192
+ modelPath: string;
193
+ host?: string;
194
+ port?: number;
195
+ params?: import('./definitions').NativeContextParams;
196
+ }): Promise<{
197
+ running: boolean;
198
+ }>;
199
+ stopNativeLlamaServer(): Promise<void>;
200
+ isNativeLlamaServerRunning(): Promise<{
201
+ running: boolean;
202
+ }>;
203
+ addListener(eventName: string, listenerFunc: (data: unknown) => void): Promise<void>;
204
+ removeAllListeners(): Promise<void>;
205
+ }
206
+ export * from './definitions';