@runanywhere/web 0.1.0-beta.5 → 0.1.0-beta.6

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 (160) hide show
  1. package/dist/Foundation/SherpaONNXBridge.d.ts +147 -0
  2. package/dist/Foundation/SherpaONNXBridge.d.ts.map +1 -0
  3. package/dist/Foundation/SherpaONNXBridge.js +345 -0
  4. package/dist/Foundation/SherpaONNXBridge.js.map +1 -0
  5. package/dist/Foundation/StructOffsets.d.ts +5 -33
  6. package/dist/Foundation/StructOffsets.d.ts.map +1 -1
  7. package/dist/Foundation/StructOffsets.js +94 -128
  8. package/dist/Foundation/StructOffsets.js.map +1 -1
  9. package/dist/Infrastructure/AudioCapture.d.ts +99 -0
  10. package/dist/Infrastructure/AudioCapture.d.ts.map +1 -0
  11. package/dist/Infrastructure/AudioCapture.js +264 -0
  12. package/dist/Infrastructure/AudioCapture.js.map +1 -0
  13. package/dist/Infrastructure/AudioPlayback.d.ts +53 -0
  14. package/dist/Infrastructure/AudioPlayback.d.ts.map +1 -0
  15. package/dist/Infrastructure/AudioPlayback.js +117 -0
  16. package/dist/Infrastructure/AudioPlayback.js.map +1 -0
  17. package/dist/Infrastructure/ModelDownloader.d.ts +5 -16
  18. package/dist/Infrastructure/ModelDownloader.d.ts.map +1 -1
  19. package/dist/Infrastructure/ModelDownloader.js +7 -54
  20. package/dist/Infrastructure/ModelDownloader.js.map +1 -1
  21. package/dist/Infrastructure/ModelLoaderTypes.d.ts +11 -76
  22. package/dist/Infrastructure/ModelLoaderTypes.d.ts.map +1 -1
  23. package/dist/Infrastructure/ModelLoaderTypes.js +1 -7
  24. package/dist/Infrastructure/ModelLoaderTypes.js.map +1 -1
  25. package/dist/Infrastructure/ModelManager.d.ts +104 -30
  26. package/dist/Infrastructure/ModelManager.d.ts.map +1 -1
  27. package/dist/Infrastructure/ModelManager.js +546 -209
  28. package/dist/Infrastructure/ModelManager.js.map +1 -1
  29. package/dist/Infrastructure/ModelRegistry.d.ts +8 -6
  30. package/dist/Infrastructure/ModelRegistry.d.ts.map +1 -1
  31. package/dist/Infrastructure/ModelRegistry.js +4 -11
  32. package/dist/Infrastructure/ModelRegistry.js.map +1 -1
  33. package/dist/Infrastructure/VLMWorkerBridge.d.ts +211 -0
  34. package/dist/Infrastructure/VLMWorkerBridge.d.ts.map +1 -0
  35. package/dist/Infrastructure/VLMWorkerBridge.js +264 -0
  36. package/dist/Infrastructure/VLMWorkerBridge.js.map +1 -0
  37. package/dist/Infrastructure/VLMWorkerRuntime.d.ts +38 -0
  38. package/dist/Infrastructure/VLMWorkerRuntime.d.ts.map +1 -0
  39. package/dist/Infrastructure/VLMWorkerRuntime.js +503 -0
  40. package/dist/Infrastructure/VLMWorkerRuntime.js.map +1 -0
  41. package/dist/Infrastructure/VideoCapture.d.ts +130 -0
  42. package/dist/Infrastructure/VideoCapture.d.ts.map +1 -0
  43. package/dist/Infrastructure/VideoCapture.js +236 -0
  44. package/dist/Infrastructure/VideoCapture.js.map +1 -0
  45. package/dist/Public/Extensions/DiffusionTypes.d.ts +64 -0
  46. package/dist/Public/Extensions/DiffusionTypes.d.ts.map +1 -0
  47. package/dist/Public/Extensions/DiffusionTypes.js +28 -0
  48. package/dist/Public/Extensions/DiffusionTypes.js.map +1 -0
  49. package/dist/Public/Extensions/EmbeddingsTypes.d.ts +33 -0
  50. package/dist/Public/Extensions/EmbeddingsTypes.d.ts.map +1 -0
  51. package/dist/Public/Extensions/EmbeddingsTypes.js +13 -0
  52. package/dist/Public/Extensions/EmbeddingsTypes.js.map +1 -0
  53. package/dist/Public/Extensions/RunAnywhere+Diffusion.d.ts +44 -0
  54. package/dist/Public/Extensions/RunAnywhere+Diffusion.d.ts.map +1 -0
  55. package/dist/Public/Extensions/RunAnywhere+Diffusion.js +189 -0
  56. package/dist/Public/Extensions/RunAnywhere+Diffusion.js.map +1 -0
  57. package/dist/Public/Extensions/RunAnywhere+Embeddings.d.ts +56 -0
  58. package/dist/Public/Extensions/RunAnywhere+Embeddings.d.ts.map +1 -0
  59. package/dist/Public/Extensions/RunAnywhere+Embeddings.js +240 -0
  60. package/dist/Public/Extensions/RunAnywhere+Embeddings.js.map +1 -0
  61. package/dist/Public/Extensions/RunAnywhere+STT.d.ts +97 -0
  62. package/dist/Public/Extensions/RunAnywhere+STT.d.ts.map +1 -0
  63. package/dist/Public/Extensions/RunAnywhere+STT.js +417 -0
  64. package/dist/Public/Extensions/RunAnywhere+STT.js.map +1 -0
  65. package/dist/Public/Extensions/RunAnywhere+StructuredOutput.d.ts +69 -0
  66. package/dist/Public/Extensions/RunAnywhere+StructuredOutput.d.ts.map +1 -0
  67. package/dist/Public/Extensions/RunAnywhere+StructuredOutput.js +196 -0
  68. package/dist/Public/Extensions/RunAnywhere+StructuredOutput.js.map +1 -0
  69. package/dist/Public/Extensions/RunAnywhere+TTS.d.ts +55 -0
  70. package/dist/Public/Extensions/RunAnywhere+TTS.d.ts.map +1 -0
  71. package/dist/Public/Extensions/RunAnywhere+TTS.js +253 -0
  72. package/dist/Public/Extensions/RunAnywhere+TTS.js.map +1 -0
  73. package/dist/Public/Extensions/RunAnywhere+TextGeneration.d.ts +80 -0
  74. package/dist/Public/Extensions/RunAnywhere+TextGeneration.d.ts.map +1 -0
  75. package/dist/Public/Extensions/RunAnywhere+TextGeneration.js +470 -0
  76. package/dist/Public/Extensions/RunAnywhere+TextGeneration.js.map +1 -0
  77. package/dist/Public/Extensions/RunAnywhere+ToolCalling.d.ts +82 -0
  78. package/dist/Public/Extensions/RunAnywhere+ToolCalling.d.ts.map +1 -0
  79. package/dist/Public/Extensions/RunAnywhere+ToolCalling.js +576 -0
  80. package/dist/Public/Extensions/RunAnywhere+ToolCalling.js.map +1 -0
  81. package/dist/Public/Extensions/RunAnywhere+VAD.d.ts +70 -0
  82. package/dist/Public/Extensions/RunAnywhere+VAD.d.ts.map +1 -0
  83. package/dist/Public/Extensions/RunAnywhere+VAD.js +231 -0
  84. package/dist/Public/Extensions/RunAnywhere+VAD.js.map +1 -0
  85. package/dist/Public/Extensions/RunAnywhere+VLM.d.ts +58 -0
  86. package/dist/Public/Extensions/RunAnywhere+VLM.d.ts.map +1 -0
  87. package/dist/Public/Extensions/RunAnywhere+VLM.js +262 -0
  88. package/dist/Public/Extensions/RunAnywhere+VLM.js.map +1 -0
  89. package/dist/Public/Extensions/RunAnywhere+VoicePipeline.d.ts +29 -3
  90. package/dist/Public/Extensions/RunAnywhere+VoicePipeline.d.ts.map +1 -1
  91. package/dist/Public/Extensions/RunAnywhere+VoicePipeline.js +42 -46
  92. package/dist/Public/Extensions/RunAnywhere+VoicePipeline.js.map +1 -1
  93. package/dist/Public/Extensions/STTTypes.d.ts +61 -0
  94. package/dist/Public/Extensions/STTTypes.d.ts.map +1 -0
  95. package/dist/Public/Extensions/STTTypes.js +16 -0
  96. package/dist/Public/Extensions/STTTypes.js.map +1 -0
  97. package/dist/Public/Extensions/TTSTypes.d.ts +31 -0
  98. package/dist/Public/Extensions/TTSTypes.d.ts.map +1 -0
  99. package/dist/Public/Extensions/TTSTypes.js +3 -0
  100. package/dist/Public/Extensions/TTSTypes.js.map +1 -0
  101. package/dist/Public/Extensions/ToolCallingTypes.d.ts +78 -0
  102. package/dist/Public/Extensions/ToolCallingTypes.d.ts.map +1 -0
  103. package/dist/Public/Extensions/ToolCallingTypes.js +8 -0
  104. package/dist/Public/Extensions/ToolCallingTypes.js.map +1 -0
  105. package/dist/Public/Extensions/VADTypes.d.ts +30 -0
  106. package/dist/Public/Extensions/VADTypes.d.ts.map +1 -0
  107. package/dist/Public/Extensions/VADTypes.js +8 -0
  108. package/dist/Public/Extensions/VADTypes.js.map +1 -0
  109. package/dist/Public/Extensions/VLMTypes.d.ts +56 -0
  110. package/dist/Public/Extensions/VLMTypes.d.ts.map +1 -0
  111. package/dist/Public/Extensions/VLMTypes.js +24 -0
  112. package/dist/Public/Extensions/VLMTypes.js.map +1 -0
  113. package/dist/Public/Extensions/VoicePipelineTypes.d.ts +37 -28
  114. package/dist/Public/Extensions/VoicePipelineTypes.d.ts.map +1 -1
  115. package/dist/Public/Extensions/VoicePipelineTypes.js +1 -4
  116. package/dist/Public/Extensions/VoicePipelineTypes.js.map +1 -1
  117. package/dist/Public/RunAnywhere.d.ts +61 -65
  118. package/dist/Public/RunAnywhere.d.ts.map +1 -1
  119. package/dist/Public/RunAnywhere.js +141 -193
  120. package/dist/Public/RunAnywhere.js.map +1 -1
  121. package/dist/index.d.ts +39 -23
  122. package/dist/index.d.ts.map +1 -1
  123. package/dist/index.js +31 -19
  124. package/dist/index.js.map +1 -1
  125. package/dist/types/LLMTypes.d.ts +48 -0
  126. package/dist/types/LLMTypes.d.ts.map +1 -0
  127. package/dist/types/LLMTypes.js +8 -0
  128. package/dist/types/LLMTypes.js.map +1 -0
  129. package/dist/types/index.d.ts +1 -0
  130. package/dist/types/index.d.ts.map +1 -1
  131. package/dist/types/index.js +0 -1
  132. package/dist/types/index.js.map +1 -1
  133. package/dist/workers/vlm-worker.d.ts +9 -0
  134. package/dist/workers/vlm-worker.d.ts.map +1 -0
  135. package/dist/workers/vlm-worker.js +10 -0
  136. package/dist/workers/vlm-worker.js.map +1 -0
  137. package/package.json +5 -1
  138. package/wasm/racommons-webgpu.js +156 -0
  139. package/wasm/racommons-webgpu.wasm +0 -0
  140. package/wasm/racommons.js +91 -91
  141. package/wasm/racommons.wasm +0 -0
  142. package/wasm/sherpa/sherpa-onnx-asr.js +1538 -0
  143. package/wasm/sherpa/sherpa-onnx-glue-original.js +19 -0
  144. package/wasm/sherpa/sherpa-onnx-glue.js +17 -0
  145. package/wasm/sherpa/sherpa-onnx-tts.js +657 -0
  146. package/wasm/sherpa/sherpa-onnx-vad.js +337 -0
  147. package/wasm/sherpa/sherpa-onnx-wave.js +88 -0
  148. package/wasm/sherpa/sherpa-onnx.wasm +0 -0
  149. package/dist/Infrastructure/ExtensionPoint.d.ts +0 -78
  150. package/dist/Infrastructure/ExtensionPoint.d.ts.map +0 -1
  151. package/dist/Infrastructure/ExtensionPoint.js +0 -118
  152. package/dist/Infrastructure/ExtensionPoint.js.map +0 -1
  153. package/dist/Infrastructure/LocalFileStorage.d.ts +0 -116
  154. package/dist/Infrastructure/LocalFileStorage.d.ts.map +0 -1
  155. package/dist/Infrastructure/LocalFileStorage.js +0 -368
  156. package/dist/Infrastructure/LocalFileStorage.js.map +0 -1
  157. package/dist/Infrastructure/ModelFileInference.d.ts +0 -39
  158. package/dist/Infrastructure/ModelFileInference.d.ts.map +0 -1
  159. package/dist/Infrastructure/ModelFileInference.js +0 -110
  160. package/dist/Infrastructure/ModelFileInference.js.map +0 -1
@@ -1,116 +0,0 @@
1
- /**
2
- * LocalFileStorage - Persistent model storage using the File System Access API
3
- *
4
- * Allows users to choose a real folder on their local filesystem for model
5
- * storage. Models are saved as actual files (e.g. ~/ai-models/smollm2.gguf)
6
- * that persist permanently — no browser eviction, no re-downloads.
7
- *
8
- * The directory handle is stored in IndexedDB (not cookies — handles are
9
- * structured-cloneable objects that can't be serialized to strings).
10
- *
11
- * Browser support:
12
- * - Chrome 122+: Full support with persistent permissions ("Allow on every visit")
13
- * - Chrome 86-121: Supported but re-prompts for permission each session
14
- * - Edge: Same as Chrome (Chromium-based)
15
- * - Firefox/Safari: NOT supported — falls back to OPFS storage
16
- *
17
- * Usage:
18
- * const storage = new LocalFileStorage();
19
- * await storage.chooseDirectory(); // User picks a folder
20
- * await storage.saveModel('model-id', data);
21
- *
22
- * // On return visit:
23
- * const restored = await storage.restoreDirectory();
24
- * if (restored) {
25
- * const data = await storage.loadModel('model-id');
26
- * }
27
- */
28
- export declare class LocalFileStorage {
29
- private dirHandle;
30
- private _isReady;
31
- private _hasStoredHandle;
32
- /** Whether the File System Access API is available in this browser. */
33
- static get isSupported(): boolean;
34
- /**
35
- * Get the stored directory name from localStorage (fast, synchronous).
36
- * Available immediately on page load before IndexedDB restores the handle.
37
- * Returns the folder name only (e.g. "ai-models"), not the full path.
38
- */
39
- static get storedDirectoryName(): string | null;
40
- /** Whether the storage is ready for use (directory selected + permission granted). */
41
- get isReady(): boolean;
42
- /** Whether a handle was found in IndexedDB (even if permission isn't granted yet). */
43
- get hasStoredHandle(): boolean;
44
- /** The name of the chosen directory (for display in UI). */
45
- get directoryName(): string | null;
46
- /**
47
- * Prompt the user to choose a directory for model storage.
48
- * Opens the OS folder picker dialog.
49
- * Stores the directory handle in IndexedDB for future sessions.
50
- *
51
- * @returns true if a directory was selected, false if cancelled
52
- */
53
- chooseDirectory(): Promise<boolean>;
54
- /**
55
- * Attempt to restore a previously chosen directory from IndexedDB.
56
- *
57
- * On Chrome 122+, if the user selected "Allow on every visit",
58
- * permission is automatically granted without any prompt.
59
- *
60
- * @returns true if directory was restored and permission is granted.
61
- * false if no handle stored or permission not granted (UI
62
- * should show a "Re-authorize" button).
63
- */
64
- restoreDirectory(): Promise<boolean>;
65
- /**
66
- * Request readwrite permission on a previously stored handle.
67
- * MUST be called from a user gesture (button click handler).
68
- *
69
- * @returns true if permission was granted
70
- */
71
- requestAccess(): Promise<boolean>;
72
- /**
73
- * Save model data to the local filesystem.
74
- * @param key - Model identifier (used as filename)
75
- * @param data - Model file data
76
- */
77
- saveModel(key: string, data: ArrayBuffer): Promise<void>;
78
- /**
79
- * Load model data from the local filesystem.
80
- * @param key - Model identifier
81
- * @returns Model data, or null if not found
82
- */
83
- loadModel(key: string): Promise<ArrayBuffer | null>;
84
- /**
85
- * Check if a model file exists in local storage.
86
- * @param key - Model identifier
87
- */
88
- hasModel(key: string): Promise<boolean>;
89
- /**
90
- * Delete a model file from local storage.
91
- * @param key - Model identifier
92
- */
93
- deleteModel(key: string): Promise<void>;
94
- /**
95
- * Get file size without reading into memory.
96
- * @param key - Model identifier
97
- */
98
- getFileSize(key: string): Promise<number | null>;
99
- /**
100
- * List all model files in the directory.
101
- */
102
- listModels(): Promise<Array<{
103
- id: string;
104
- sizeBytes: number;
105
- lastModified: number;
106
- }>>;
107
- private openDB;
108
- private storeHandle;
109
- private retrieveHandle;
110
- /**
111
- * Sanitize a key for use as a filename.
112
- * Keeps alphanumeric, dots, dashes, underscores. Replaces everything else.
113
- */
114
- private sanitizeFilename;
115
- }
116
- //# sourceMappingURL=LocalFileStorage.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"LocalFileStorage.d.ts","sourceRoot":"","sources":["../../src/Infrastructure/LocalFileStorage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAoCH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAA0C;IAC3D,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,gBAAgB,CAAS;IAMjC,uEAAuE;IACvE,MAAM,KAAK,WAAW,IAAI,OAAO,CAEhC;IAED;;;;OAIG;IACH,MAAM,KAAK,mBAAmB,IAAI,MAAM,GAAG,IAAI,CAM9C;IAMD,sFAAsF;IACtF,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,sFAAsF;IACtF,IAAI,eAAe,IAAI,OAAO,CAE7B;IAED,4DAA4D;IAC5D,IAAI,aAAa,IAAI,MAAM,GAAG,IAAI,CAEjC;IAMD;;;;;;OAMG;IACG,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAiCzC;;;;;;;;;OASG;IACG,gBAAgB,IAAI,OAAO,CAAC,OAAO,CAAC;IAkC1C;;;;;OAKG;IACG,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC;IA0BvC;;;;OAIG;IACG,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB9D;;;;OAIG;IACG,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAczD;;;OAGG;IACG,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAY7C;;;OAGG;IACG,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAY7C;;;OAGG;IACG,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAatD;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;YAwB7E,MAAM;YAgBN,WAAW;YAiBX,cAAc;IAsB5B;;;OAGG;IACH,OAAO,CAAC,gBAAgB;CAGzB"}
@@ -1,368 +0,0 @@
1
- /**
2
- * LocalFileStorage - Persistent model storage using the File System Access API
3
- *
4
- * Allows users to choose a real folder on their local filesystem for model
5
- * storage. Models are saved as actual files (e.g. ~/ai-models/smollm2.gguf)
6
- * that persist permanently — no browser eviction, no re-downloads.
7
- *
8
- * The directory handle is stored in IndexedDB (not cookies — handles are
9
- * structured-cloneable objects that can't be serialized to strings).
10
- *
11
- * Browser support:
12
- * - Chrome 122+: Full support with persistent permissions ("Allow on every visit")
13
- * - Chrome 86-121: Supported but re-prompts for permission each session
14
- * - Edge: Same as Chrome (Chromium-based)
15
- * - Firefox/Safari: NOT supported — falls back to OPFS storage
16
- *
17
- * Usage:
18
- * const storage = new LocalFileStorage();
19
- * await storage.chooseDirectory(); // User picks a folder
20
- * await storage.saveModel('model-id', data);
21
- *
22
- * // On return visit:
23
- * const restored = await storage.restoreDirectory();
24
- * if (restored) {
25
- * const data = await storage.loadModel('model-id');
26
- * }
27
- */
28
- import { SDKLogger } from '../Foundation/SDKLogger';
29
- const logger = new SDKLogger('LocalFileStorage');
30
- /* eslint-enable @typescript-eslint/no-explicit-any */
31
- // ---------------------------------------------------------------------------
32
- // IndexedDB Constants
33
- // ---------------------------------------------------------------------------
34
- const DB_NAME = 'runanywhere-storage';
35
- const DB_VERSION = 1;
36
- const STORE_NAME = 'handles';
37
- const HANDLE_KEY = 'modelDirectory';
38
- const LS_DIR_NAME_KEY = 'runanywhere_storage_dir_name';
39
- // ---------------------------------------------------------------------------
40
- // LocalFileStorage
41
- // ---------------------------------------------------------------------------
42
- export class LocalFileStorage {
43
- dirHandle = null;
44
- _isReady = false;
45
- _hasStoredHandle = false;
46
- // -------------------------------------------------------------------------
47
- // Static
48
- // -------------------------------------------------------------------------
49
- /** Whether the File System Access API is available in this browser. */
50
- static get isSupported() {
51
- return typeof window !== 'undefined' && 'showDirectoryPicker' in window;
52
- }
53
- /**
54
- * Get the stored directory name from localStorage (fast, synchronous).
55
- * Available immediately on page load before IndexedDB restores the handle.
56
- * Returns the folder name only (e.g. "ai-models"), not the full path.
57
- */
58
- static get storedDirectoryName() {
59
- try {
60
- return localStorage.getItem(LS_DIR_NAME_KEY);
61
- }
62
- catch {
63
- return null;
64
- }
65
- }
66
- // -------------------------------------------------------------------------
67
- // State
68
- // -------------------------------------------------------------------------
69
- /** Whether the storage is ready for use (directory selected + permission granted). */
70
- get isReady() {
71
- return this._isReady && this.dirHandle !== null;
72
- }
73
- /** Whether a handle was found in IndexedDB (even if permission isn't granted yet). */
74
- get hasStoredHandle() {
75
- return this._hasStoredHandle;
76
- }
77
- /** The name of the chosen directory (for display in UI). */
78
- get directoryName() {
79
- return this.dirHandle?.name ?? null;
80
- }
81
- // -------------------------------------------------------------------------
82
- // Directory Selection
83
- // -------------------------------------------------------------------------
84
- /**
85
- * Prompt the user to choose a directory for model storage.
86
- * Opens the OS folder picker dialog.
87
- * Stores the directory handle in IndexedDB for future sessions.
88
- *
89
- * @returns true if a directory was selected, false if cancelled
90
- */
91
- async chooseDirectory() {
92
- if (!LocalFileStorage.isSupported) {
93
- logger.warning('File System Access API not supported in this browser');
94
- return false;
95
- }
96
- try {
97
- // showDirectoryPicker requires user gesture (button click)
98
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
99
- this.dirHandle = await window.showDirectoryPicker({
100
- mode: 'readwrite',
101
- });
102
- await this.storeHandle(this.dirHandle);
103
- this._isReady = true;
104
- this._hasStoredHandle = true;
105
- // Persist directory name in localStorage for fast UI display on next visit
106
- try {
107
- localStorage.setItem(LS_DIR_NAME_KEY, this.dirHandle.name);
108
- }
109
- catch { /* non-critical */ }
110
- logger.info(`Local storage directory selected: ${this.dirHandle.name}`);
111
- return true;
112
- }
113
- catch (err) {
114
- if (err instanceof Error && err.name === 'AbortError') {
115
- logger.debug('User cancelled directory picker');
116
- return false;
117
- }
118
- const message = err instanceof Error ? err.message : String(err);
119
- logger.error(`Failed to choose directory: ${message}`);
120
- return false;
121
- }
122
- }
123
- /**
124
- * Attempt to restore a previously chosen directory from IndexedDB.
125
- *
126
- * On Chrome 122+, if the user selected "Allow on every visit",
127
- * permission is automatically granted without any prompt.
128
- *
129
- * @returns true if directory was restored and permission is granted.
130
- * false if no handle stored or permission not granted (UI
131
- * should show a "Re-authorize" button).
132
- */
133
- async restoreDirectory() {
134
- if (!LocalFileStorage.isSupported)
135
- return false;
136
- try {
137
- const handle = await this.retrieveHandle();
138
- if (!handle) {
139
- logger.debug('No stored directory handle found');
140
- return false;
141
- }
142
- this._hasStoredHandle = true;
143
- this.dirHandle = handle;
144
- // queryPermission does NOT require user gesture
145
- const permission = await handle.queryPermission({ mode: 'readwrite' });
146
- if (permission === 'granted') {
147
- this._isReady = true;
148
- logger.info(`Local storage restored: ${handle.name}`);
149
- return true;
150
- }
151
- // Permission not granted yet — user needs to click a button
152
- // to trigger requestPermission() via requestAccess()
153
- logger.debug(`Local storage handle found but permission is '${permission}' — needs re-authorization`);
154
- this._isReady = false;
155
- return false;
156
- }
157
- catch (err) {
158
- const message = err instanceof Error ? err.message : String(err);
159
- logger.warning(`Failed to restore directory: ${message}`);
160
- return false;
161
- }
162
- }
163
- /**
164
- * Request readwrite permission on a previously stored handle.
165
- * MUST be called from a user gesture (button click handler).
166
- *
167
- * @returns true if permission was granted
168
- */
169
- async requestAccess() {
170
- if (!this.dirHandle) {
171
- logger.warning('No directory handle to request access for');
172
- return false;
173
- }
174
- try {
175
- const permission = await this.dirHandle.requestPermission({ mode: 'readwrite' });
176
- if (permission === 'granted') {
177
- this._isReady = true;
178
- logger.info(`Local storage re-authorized: ${this.dirHandle.name}`);
179
- return true;
180
- }
181
- logger.debug(`Permission request result: ${permission}`);
182
- return false;
183
- }
184
- catch (err) {
185
- const message = err instanceof Error ? err.message : String(err);
186
- logger.warning(`Permission request failed: ${message}`);
187
- return false;
188
- }
189
- }
190
- // -------------------------------------------------------------------------
191
- // Model Operations
192
- // -------------------------------------------------------------------------
193
- /**
194
- * Save model data to the local filesystem.
195
- * @param key - Model identifier (used as filename)
196
- * @param data - Model file data
197
- */
198
- async saveModel(key, data) {
199
- if (!this.dirHandle || !this._isReady) {
200
- throw new Error('LocalFileStorage not ready — call chooseDirectory() or restoreDirectory() first.');
201
- }
202
- const filename = this.sanitizeFilename(key);
203
- const fileHandle = await this.dirHandle.getFileHandle(filename, { create: true });
204
- const writable = await fileHandle.createWritable();
205
- try {
206
- await writable.write(data);
207
- await writable.close();
208
- logger.info(`Saved model to local storage: ${filename} (${(data.byteLength / 1024 / 1024).toFixed(1)} MB)`);
209
- }
210
- catch (err) {
211
- try {
212
- await writable.abort();
213
- }
214
- catch { /* ignore */ }
215
- throw err;
216
- }
217
- }
218
- /**
219
- * Load model data from the local filesystem.
220
- * @param key - Model identifier
221
- * @returns Model data, or null if not found
222
- */
223
- async loadModel(key) {
224
- if (!this.dirHandle || !this._isReady)
225
- return null;
226
- try {
227
- const filename = this.sanitizeFilename(key);
228
- const fileHandle = await this.dirHandle.getFileHandle(filename);
229
- const file = await fileHandle.getFile();
230
- logger.info(`Loaded model from local storage: ${filename} (${(file.size / 1024 / 1024).toFixed(1)} MB)`);
231
- return await file.arrayBuffer();
232
- }
233
- catch {
234
- return null; // File not found
235
- }
236
- }
237
- /**
238
- * Check if a model file exists in local storage.
239
- * @param key - Model identifier
240
- */
241
- async hasModel(key) {
242
- if (!this.dirHandle || !this._isReady)
243
- return false;
244
- try {
245
- const filename = this.sanitizeFilename(key);
246
- await this.dirHandle.getFileHandle(filename);
247
- return true;
248
- }
249
- catch {
250
- return false;
251
- }
252
- }
253
- /**
254
- * Delete a model file from local storage.
255
- * @param key - Model identifier
256
- */
257
- async deleteModel(key) {
258
- if (!this.dirHandle || !this._isReady)
259
- return;
260
- try {
261
- const filename = this.sanitizeFilename(key);
262
- await this.dirHandle.removeEntry(filename);
263
- logger.info(`Deleted model from local storage: ${filename}`);
264
- }
265
- catch {
266
- // File doesn't exist
267
- }
268
- }
269
- /**
270
- * Get file size without reading into memory.
271
- * @param key - Model identifier
272
- */
273
- async getFileSize(key) {
274
- if (!this.dirHandle || !this._isReady)
275
- return null;
276
- try {
277
- const filename = this.sanitizeFilename(key);
278
- const fileHandle = await this.dirHandle.getFileHandle(filename);
279
- const file = await fileHandle.getFile();
280
- return file.size;
281
- }
282
- catch {
283
- return null;
284
- }
285
- }
286
- /**
287
- * List all model files in the directory.
288
- */
289
- async listModels() {
290
- if (!this.dirHandle || !this._isReady)
291
- return [];
292
- const models = [];
293
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
294
- for await (const [name, handle] of this.dirHandle.entries()) {
295
- if (handle.kind === 'file') {
296
- const file = await handle.getFile();
297
- models.push({
298
- id: name,
299
- sizeBytes: file.size,
300
- lastModified: file.lastModified,
301
- });
302
- }
303
- }
304
- return models;
305
- }
306
- // -------------------------------------------------------------------------
307
- // IndexedDB Handle Persistence
308
- // -------------------------------------------------------------------------
309
- async openDB() {
310
- return new Promise((resolve, reject) => {
311
- const request = indexedDB.open(DB_NAME, DB_VERSION);
312
- request.onupgradeneeded = () => {
313
- const db = request.result;
314
- if (!db.objectStoreNames.contains(STORE_NAME)) {
315
- db.createObjectStore(STORE_NAME);
316
- }
317
- };
318
- request.onsuccess = () => resolve(request.result);
319
- request.onerror = () => reject(request.error);
320
- });
321
- }
322
- async storeHandle(handle) {
323
- try {
324
- const db = await this.openDB();
325
- const tx = db.transaction(STORE_NAME, 'readwrite');
326
- tx.objectStore(STORE_NAME).put(handle, HANDLE_KEY);
327
- await new Promise((resolve, reject) => {
328
- tx.oncomplete = () => resolve();
329
- tx.onerror = () => reject(tx.error);
330
- });
331
- db.close();
332
- logger.debug('Directory handle stored in IndexedDB');
333
- }
334
- catch (err) {
335
- const message = err instanceof Error ? err.message : String(err);
336
- logger.warning(`Failed to store handle in IndexedDB: ${message}`);
337
- }
338
- }
339
- async retrieveHandle() {
340
- try {
341
- const db = await this.openDB();
342
- const tx = db.transaction(STORE_NAME, 'readonly');
343
- const handle = await new Promise((resolve, reject) => {
344
- const req = tx.objectStore(STORE_NAME).get(HANDLE_KEY);
345
- req.onsuccess = () => resolve(req.result ?? null);
346
- req.onerror = () => reject(req.error);
347
- });
348
- db.close();
349
- return handle;
350
- }
351
- catch (err) {
352
- const message = err instanceof Error ? err.message : String(err);
353
- logger.warning(`Failed to retrieve handle from IndexedDB: ${message}`);
354
- return null;
355
- }
356
- }
357
- // -------------------------------------------------------------------------
358
- // Helpers
359
- // -------------------------------------------------------------------------
360
- /**
361
- * Sanitize a key for use as a filename.
362
- * Keeps alphanumeric, dots, dashes, underscores. Replaces everything else.
363
- */
364
- sanitizeFilename(key) {
365
- return key.replace(/[<>:"/\\|?*\x00-\x1F]/g, '_');
366
- }
367
- }
368
- //# sourceMappingURL=LocalFileStorage.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"LocalFileStorage.js","sourceRoot":"","sources":["../../src/Infrastructure/LocalFileStorage.ts"],"names":[],"mappings":"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"}
@@ -1,39 +0,0 @@
1
- /**
2
- * Model File Inference - Infer model metadata from filenames
3
- *
4
- * When a user imports a model file via picker or drag-and-drop,
5
- * we need to determine the model type, framework, and a human-friendly
6
- * name from the filename alone.
7
- *
8
- * Usage:
9
- * import { inferModelFromFilename } from './ModelFileInference';
10
- * const meta = inferModelFromFilename('smollm2-360m.Q8_0.gguf');
11
- * // { id: 'smollm2-360m-q8_0', name: 'smollm2-360m.Q8_0', category: Language, framework: LlamaCpp }
12
- */
13
- import { ModelCategory, LLMFramework } from '../types/enums';
14
- export interface InferredModelMeta {
15
- /** Sanitized model ID (lowercase, no special chars). */
16
- id: string;
17
- /** Human-readable display name. */
18
- name: string;
19
- /** Inferred model category. */
20
- category: ModelCategory;
21
- /** Inferred inference framework. */
22
- framework: LLMFramework;
23
- }
24
- /**
25
- * Infer model metadata from a filename.
26
- *
27
- * Rules:
28
- * - `.gguf` -> Language model, LlamaCpp framework
29
- * - `.onnx` -> Depends on filename keywords (vad/tts/stt/whisper/silero)
30
- * - `.bin` -> Language model, LlamaCpp framework (generic)
31
- * - Other -> Language model, LlamaCpp framework (best guess)
32
- */
33
- export declare function inferModelFromFilename(filename: string): InferredModelMeta;
34
- /**
35
- * Sanitize a filename into a valid model ID.
36
- * Lowercase, replace non-alphanumeric with dashes, collapse multiples.
37
- */
38
- export declare function sanitizeId(name: string): string;
39
- //# sourceMappingURL=ModelFileInference.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ModelFileInference.d.ts","sourceRoot":"","sources":["../../src/Infrastructure/ModelFileInference.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAM7D,MAAM,WAAW,iBAAiB;IAChC,wDAAwD;IACxD,EAAE,EAAE,MAAM,CAAC;IACX,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,QAAQ,EAAE,aAAa,CAAC;IACxB,oCAAoC;IACpC,SAAS,EAAE,YAAY,CAAC;CACzB;AAMD;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,CAyD1E;AAgBD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAK/C"}
@@ -1,110 +0,0 @@
1
- /**
2
- * Model File Inference - Infer model metadata from filenames
3
- *
4
- * When a user imports a model file via picker or drag-and-drop,
5
- * we need to determine the model type, framework, and a human-friendly
6
- * name from the filename alone.
7
- *
8
- * Usage:
9
- * import { inferModelFromFilename } from './ModelFileInference';
10
- * const meta = inferModelFromFilename('smollm2-360m.Q8_0.gguf');
11
- * // { id: 'smollm2-360m-q8_0', name: 'smollm2-360m.Q8_0', category: Language, framework: LlamaCpp }
12
- */
13
- import { ModelCategory, LLMFramework } from '../types/enums';
14
- // ---------------------------------------------------------------------------
15
- // Inference
16
- // ---------------------------------------------------------------------------
17
- /**
18
- * Infer model metadata from a filename.
19
- *
20
- * Rules:
21
- * - `.gguf` -> Language model, LlamaCpp framework
22
- * - `.onnx` -> Depends on filename keywords (vad/tts/stt/whisper/silero)
23
- * - `.bin` -> Language model, LlamaCpp framework (generic)
24
- * - Other -> Language model, LlamaCpp framework (best guess)
25
- */
26
- export function inferModelFromFilename(filename) {
27
- const ext = getExtension(filename);
28
- const baseName = stripExtension(filename);
29
- const lowerName = baseName.toLowerCase();
30
- if (ext === 'gguf') {
31
- return {
32
- id: sanitizeId(baseName),
33
- name: humanizeName(baseName),
34
- category: ModelCategory.Language,
35
- framework: LLMFramework.LlamaCpp,
36
- };
37
- }
38
- if (ext === 'onnx') {
39
- // Infer category from filename keywords
40
- if (lowerName.includes('vad') || lowerName.includes('silero_vad')) {
41
- return {
42
- id: sanitizeId(baseName),
43
- name: humanizeName(baseName),
44
- category: ModelCategory.Audio,
45
- framework: LLMFramework.ONNX,
46
- };
47
- }
48
- if (lowerName.includes('tts') || lowerName.includes('piper') || lowerName.includes('vits')) {
49
- return {
50
- id: sanitizeId(baseName),
51
- name: humanizeName(baseName),
52
- category: ModelCategory.SpeechSynthesis,
53
- framework: LLMFramework.ONNX,
54
- };
55
- }
56
- if (lowerName.includes('whisper') || lowerName.includes('encoder') || lowerName.includes('decoder')
57
- || lowerName.includes('paraformer') || lowerName.includes('zipformer') || lowerName.includes('stt')) {
58
- return {
59
- id: sanitizeId(baseName),
60
- name: humanizeName(baseName),
61
- category: ModelCategory.SpeechRecognition,
62
- framework: LLMFramework.ONNX,
63
- };
64
- }
65
- // Default ONNX -> STT
66
- return {
67
- id: sanitizeId(baseName),
68
- name: humanizeName(baseName),
69
- category: ModelCategory.SpeechRecognition,
70
- framework: LLMFramework.ONNX,
71
- };
72
- }
73
- // Default: treat as LLM GGUF model
74
- return {
75
- id: sanitizeId(baseName),
76
- name: humanizeName(baseName),
77
- category: ModelCategory.Language,
78
- framework: LLMFramework.LlamaCpp,
79
- };
80
- }
81
- // ---------------------------------------------------------------------------
82
- // Helpers
83
- // ---------------------------------------------------------------------------
84
- function getExtension(filename) {
85
- const lastDot = filename.lastIndexOf('.');
86
- return lastDot >= 0 ? filename.slice(lastDot + 1).toLowerCase() : '';
87
- }
88
- function stripExtension(filename) {
89
- const lastDot = filename.lastIndexOf('.');
90
- return lastDot >= 0 ? filename.slice(0, lastDot) : filename;
91
- }
92
- /**
93
- * Sanitize a filename into a valid model ID.
94
- * Lowercase, replace non-alphanumeric with dashes, collapse multiples.
95
- */
96
- export function sanitizeId(name) {
97
- return name
98
- .toLowerCase()
99
- .replace(/[^a-z0-9]+/g, '-')
100
- .replace(/^-|-$/g, '');
101
- }
102
- /**
103
- * Create a human-readable name from a filename.
104
- * Preserves case and dots (e.g. "smollm2-360m.Q8_0" stays readable).
105
- */
106
- function humanizeName(baseName) {
107
- // Replace underscores with spaces, keep dots and dashes
108
- return baseName.replace(/_/g, ' ');
109
- }
110
- //# sourceMappingURL=ModelFileInference.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ModelFileInference.js","sourceRoot":"","sources":["../../src/Infrastructure/ModelFileInference.ts"],"names":[],"mappings":"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"}