@qvac/sdk 0.4.1 → 0.5.0

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 (179) hide show
  1. package/README.md +328 -200
  2. package/dist/client/api/completion-stream.d.ts +15 -5
  3. package/dist/client/api/completion-stream.js +50 -14
  4. package/dist/client/api/embed.d.ts +17 -3
  5. package/dist/client/api/embed.js +0 -8
  6. package/dist/client/api/get-model-info.d.ts +1 -1
  7. package/dist/client/api/index.d.ts +0 -1
  8. package/dist/client/api/index.js +0 -1
  9. package/dist/client/api/load-model.d.ts +37 -11
  10. package/dist/client/api/load-model.js +29 -117
  11. package/dist/client/api/logging-stream.d.ts +6 -3
  12. package/dist/client/api/logging-stream.js +6 -3
  13. package/dist/client/api/unload-model.js +5 -2
  14. package/dist/client/config-loader/config-utils.d.ts +5 -0
  15. package/dist/client/config-loader/config-utils.js +20 -0
  16. package/dist/client/config-loader/resolve-config.bare.d.ts +9 -0
  17. package/dist/client/config-loader/resolve-config.bare.js +87 -0
  18. package/dist/client/config-loader/resolve-config.expo.d.ts +11 -0
  19. package/dist/client/config-loader/resolve-config.expo.js +62 -0
  20. package/dist/client/config-loader/resolve-config.node.d.ts +9 -0
  21. package/dist/client/config-loader/resolve-config.node.js +118 -0
  22. package/dist/client/init-hooks.d.ts +17 -3
  23. package/dist/client/init-hooks.js +37 -18
  24. package/dist/client/logging-stream-registry.d.ts +1 -1
  25. package/dist/client/logging-stream-registry.js +14 -13
  26. package/dist/client/rpc/bare-client.d.ts +10 -14
  27. package/dist/client/rpc/bare-client.js +28 -2
  28. package/dist/client/rpc/bare-rpc-client.d.ts +1 -1
  29. package/dist/client/rpc/bare-rpc-client.js +16 -13
  30. package/dist/client/rpc/expo-rpc-client.d.ts +2 -2
  31. package/dist/client/rpc/expo-rpc-client.js +15 -12
  32. package/dist/client/rpc/node-rpc-client.d.ts +1 -1
  33. package/dist/client/rpc/node-rpc-client.js +10 -7
  34. package/dist/client/rpc/rpc-client.js +16 -15
  35. package/dist/examples/config/config-path.d.ts +8 -0
  36. package/dist/examples/config/config-path.js +13 -0
  37. package/dist/examples/config-reload.d.ts +2 -0
  38. package/dist/examples/config-reload.js +49 -0
  39. package/dist/examples/download-with-blind-relays.js +20 -20
  40. package/dist/examples/embed-hyperdrive.js +35 -3
  41. package/dist/examples/kv-cache-cleanup.js +1 -1
  42. package/dist/examples/kv-cache-custom-key.js +1 -1
  43. package/dist/examples/kv-cache-example.js +1 -1
  44. package/dist/examples/llamacpp-hyperdrive.js +1 -1
  45. package/dist/examples/llamacpp-sharded.js +1 -1
  46. package/dist/examples/logging-file-transport.d.ts +2 -0
  47. package/dist/examples/{llamacpp-file-logging.js → logging-file-transport.js} +3 -7
  48. package/dist/examples/logging-streaming.d.ts +2 -0
  49. package/dist/examples/logging-streaming.js +75 -0
  50. package/dist/examples/mcp-websearch.d.ts +13 -0
  51. package/dist/examples/mcp-websearch.js +176 -0
  52. package/dist/index.d.ts +4 -4
  53. package/dist/index.js +2 -2
  54. package/dist/logging/addon.d.ts +6 -0
  55. package/dist/logging/addon.js +59 -0
  56. package/dist/logging/base-logger.js +24 -14
  57. package/dist/logging/client-logger.d.ts +3 -0
  58. package/dist/logging/client-logger.js +13 -0
  59. package/dist/logging/index.d.ts +6 -1
  60. package/dist/logging/index.js +6 -1
  61. package/dist/logging/logger.d.ts +0 -2
  62. package/dist/logging/logger.js +0 -3
  63. package/dist/logging/namespaces.d.ts +11 -0
  64. package/dist/logging/namespaces.js +11 -0
  65. package/dist/logging/registry.d.ts +26 -0
  66. package/dist/logging/registry.js +36 -0
  67. package/dist/logging/server-logger.d.ts +3 -0
  68. package/dist/logging/server-logger.js +16 -0
  69. package/dist/logging/stream-logger.d.ts +1 -1
  70. package/dist/logging/stream-logger.js +6 -3
  71. package/dist/logging/types.d.ts +2 -0
  72. package/dist/models/hyperdrive/models.d.ts +789 -51
  73. package/dist/models/hyperdrive/models.js +979 -200
  74. package/dist/schemas/common.d.ts +86 -23
  75. package/dist/schemas/common.js +0 -3
  76. package/dist/schemas/download-asset.d.ts +5 -5
  77. package/dist/schemas/embed.d.ts +3 -3
  78. package/dist/schemas/embed.js +9 -2
  79. package/dist/schemas/get-model-info.d.ts +2 -2
  80. package/dist/schemas/index.d.ts +5 -1
  81. package/dist/schemas/index.js +5 -1
  82. package/dist/schemas/json-schema.d.ts +16 -0
  83. package/dist/schemas/json-schema.js +2 -0
  84. package/dist/schemas/llamacpp-config.d.ts +5 -4
  85. package/dist/schemas/llamacpp-config.js +7 -5
  86. package/dist/schemas/load-model.d.ts +931 -211
  87. package/dist/schemas/load-model.js +7 -1
  88. package/dist/schemas/logging-stream.d.ts +10 -3
  89. package/dist/schemas/logging-stream.js +4 -3
  90. package/dist/schemas/mcp-adapter.d.ts +47 -0
  91. package/dist/schemas/mcp-adapter.js +1 -0
  92. package/dist/schemas/model-src-utils.d.ts +8 -6
  93. package/dist/schemas/model-src-utils.js +8 -3
  94. package/dist/schemas/reload-config.d.ts +344 -0
  95. package/dist/schemas/reload-config.js +42 -0
  96. package/dist/schemas/sdk-config.d.ts +22 -0
  97. package/dist/schemas/sdk-config.js +33 -0
  98. package/dist/schemas/sdk-errors-client.d.ts +4 -0
  99. package/dist/schemas/sdk-errors-client.js +20 -0
  100. package/dist/schemas/sdk-errors-server.d.ts +3 -0
  101. package/dist/schemas/sdk-errors-server.js +15 -0
  102. package/dist/schemas/tools.d.ts +3 -0
  103. package/dist/schemas/translation-config.d.ts +81 -0
  104. package/dist/schemas/translation-config.js +3 -4
  105. package/dist/schemas/whispercpp-config.d.ts +9 -1
  106. package/dist/schemas/whispercpp-config.js +2 -1
  107. package/dist/server/bare/addons/llamacpp/create-model.js +13 -4
  108. package/dist/server/bare/addons/llamacpp/handlers/embed.d.ts +9 -1
  109. package/dist/server/bare/addons/llamacpp/handlers/embed.js +18 -4
  110. package/dist/server/bare/addons/llamacpp/kv-cache-utils.js +6 -4
  111. package/dist/server/bare/addons/load-model.js +10 -4
  112. package/dist/server/bare/addons/unload-model.js +6 -3
  113. package/dist/server/bare/addons/whispercpp/handlers/transcribe-stream.js +56 -37
  114. package/dist/server/bare/delegate-rpc-client.js +12 -10
  115. package/dist/server/bare/hyperswarm.js +7 -5
  116. package/dist/server/bare/rag-hyperdb/rag-manager.js +3 -1
  117. package/dist/server/bare/registry/config-registry.d.ts +13 -4
  118. package/dist/server/bare/registry/config-registry.js +42 -10
  119. package/dist/server/bare/registry/logging-stream-registry.d.ts +24 -7
  120. package/dist/server/bare/registry/logging-stream-registry.js +99 -20
  121. package/dist/server/bare/registry/model-registry.d.ts +3 -0
  122. package/dist/server/bare/registry/model-registry.js +9 -6
  123. package/dist/server/rpc/create-server.js +5 -3
  124. package/dist/server/rpc/handle-request.js +30 -16
  125. package/dist/server/rpc/handlers/cancelHandler.js +3 -1
  126. package/dist/server/rpc/handlers/completion-stream-delegated.js +4 -2
  127. package/dist/server/rpc/handlers/delete-cache.js +3 -1
  128. package/dist/server/rpc/handlers/download-asset.js +3 -1
  129. package/dist/server/rpc/handlers/embed.js +3 -1
  130. package/dist/server/rpc/handlers/index.d.ts +0 -1
  131. package/dist/server/rpc/handlers/index.js +0 -2
  132. package/dist/server/rpc/handlers/load-model/download-manager.js +4 -2
  133. package/dist/server/rpc/handlers/load-model/http.js +20 -18
  134. package/dist/server/rpc/handlers/load-model/hyperdrive.js +21 -19
  135. package/dist/server/rpc/handlers/load-model/resolve.js +7 -5
  136. package/dist/server/rpc/handlers/load-model-delegated.d.ts +2 -2
  137. package/dist/server/rpc/handlers/load-model-delegated.js +10 -8
  138. package/dist/server/rpc/handlers/load-model.js +55 -3
  139. package/dist/server/rpc/handlers/logging-stream.js +4 -4
  140. package/dist/server/rpc/handlers/provideHandler/connection.js +12 -10
  141. package/dist/server/rpc/handlers/provideHandler/handler.js +18 -16
  142. package/dist/server/rpc/handlers/provideHandler/proxy.js +8 -6
  143. package/dist/server/rpc/handlers/rag.js +3 -1
  144. package/dist/server/rpc/handlers/stopProvideHandler.js +3 -1
  145. package/dist/server/rpc/handlers/transcribe-stream.js +3 -1
  146. package/dist/server/rpc/handlers/translate.js +3 -1
  147. package/dist/server/rpc/handlers/unload-model.js +4 -2
  148. package/dist/server/utils/audio/decoder.d.ts +2 -1
  149. package/dist/server/utils/audio/decoder.js +48 -11
  150. package/dist/server/utils/cache.js +7 -5
  151. package/dist/server/utils/config-transform.d.ts +3 -0
  152. package/dist/server/utils/config-transform.js +21 -0
  153. package/dist/server/utils/index.d.ts +1 -0
  154. package/dist/server/utils/index.js +1 -0
  155. package/dist/server/worker.js +41 -16
  156. package/dist/utils/errors-client.d.ts +12 -0
  157. package/dist/utils/errors-client.js +20 -0
  158. package/dist/utils/errors-server.d.ts +9 -0
  159. package/dist/utils/errors-server.js +16 -0
  160. package/dist/utils/getProcessSafe.d.ts +7 -0
  161. package/dist/utils/getProcessSafe.js +17 -0
  162. package/dist/utils/mcp-adapter.d.ts +12 -0
  163. package/dist/utils/mcp-adapter.js +103 -0
  164. package/dist/utils/object.d.ts +2 -0
  165. package/dist/utils/object.js +3 -0
  166. package/dist/utils/runtime.d.ts +30 -0
  167. package/dist/utils/runtime.js +48 -0
  168. package/dist/utils/tool-helpers.d.ts +10 -2
  169. package/dist/utils/tool-helpers.js +24 -11
  170. package/package.json +46 -33
  171. package/dist/client/api/set-config.d.ts +0 -7
  172. package/dist/client/api/set-config.js +0 -20
  173. package/dist/client/config-manager.d.ts +0 -4
  174. package/dist/client/config-manager.js +0 -8
  175. package/dist/examples/llamacpp-file-logging.d.ts +0 -2
  176. package/dist/schemas/set-config.d.ts +0 -21
  177. package/dist/schemas/set-config.js +0 -14
  178. package/dist/server/rpc/handlers/set-config.d.ts +0 -3
  179. package/dist/server/rpc/handlers/set-config.js +0 -18
@@ -1,4 +1,6 @@
1
1
  import {} from "../../../../schemas/index.js";
2
+ import { getServerLogger } from "../../../../logging/index.js";
3
+ const logger = getServerLogger();
2
4
  const activeDownloads = new Map();
3
5
  const clearCacheFlags = new Map();
4
6
  export const getActiveDownload = (key) => activeDownloads.get(key);
@@ -33,7 +35,7 @@ export const createCancelFunction = (downloadKey, clearCache = false) => () => {
33
35
  unregisterDownload(downloadKey);
34
36
  };
35
37
  export const cancelAllDownloads = () => {
36
- console.log(`🧹 Cancelling ${activeDownloads.size} active downloads`);
38
+ logger.info(`🧹 Cancelling ${activeDownloads.size} active downloads`);
37
39
  Array.from(activeDownloads.keys()).forEach((key) => createCancelFunction(key)());
38
40
  };
39
41
  let isCleaningUp = false;
@@ -49,6 +51,6 @@ export const cleanupDownloads = async () => {
49
51
  }
50
52
  }
51
53
  catch (error) {
52
- console.error("❌ Error during download cleanup:", error);
54
+ logger.error("❌ Error during download cleanup:", error);
53
55
  }
54
56
  };
@@ -5,6 +5,8 @@ import { AbortController } from "bare-abort-controller";
5
5
  import { getModelsCacheDir, generateShortHash } from "../../../utils/index.js";
6
6
  import { getActiveDownload, registerDownload, unregisterDownload, createHttpDownloadKey, shouldClearCache, clearClearCacheFlag, } from "./download-manager.js";
7
7
  import { DownloadCancelledError, HTTPError, NoResponseBodyError, ResponseBodyNotReadableError, } from "../../../../utils/errors-server.js";
8
+ import { getServerLogger } from "../../../../logging/index.js";
9
+ const logger = getServerLogger();
8
10
  function extractFilenameFromUrl(url) {
9
11
  // Parse URL to get the filename from the path
10
12
  const urlParts = url.split("/");
@@ -28,14 +30,14 @@ async function validateCachedFile(modelPath, url, signal) {
28
30
  expectedSize = parseInt(response.headers.get("content-length") || "0");
29
31
  }
30
32
  catch (error) {
31
- console.log(`⚠️ Could not get expected file size from HEAD request, will re-download: ${String(error)}`);
33
+ logger.warn(`⚠️ Could not get expected file size from HEAD request, will re-download: ${String(error)}`);
32
34
  return null;
33
35
  }
34
36
  if (localSize !== expectedSize) {
35
- console.log(`📥 Cached file size mismatch. Expected: ${expectedSize}, Found: ${localSize}. Re-downloading...`);
37
+ logger.info(`📥 Cached file size mismatch. Expected: ${expectedSize}, Found: ${localSize}. Re-downloading...`);
36
38
  return null;
37
39
  }
38
- console.log(`✅ Using cached HTTP model: ${modelPath}`);
40
+ logger.info(`✅ Using cached HTTP model: ${modelPath}`);
39
41
  return modelPath;
40
42
  }
41
43
  catch {
@@ -47,7 +49,7 @@ async function performHttpDownload(url, modelPath, downloadKey, progressCallback
47
49
  if (signal?.aborted) {
48
50
  throw new DownloadCancelledError();
49
51
  }
50
- console.log(`📥 Downloading model from HTTP: ${url}`);
52
+ logger.info(`📥 Downloading model from HTTP: ${url}`);
51
53
  // Check if file exists for resuming
52
54
  let startOffset = 0;
53
55
  let downloadedBytes = 0;
@@ -55,10 +57,10 @@ async function performHttpDownload(url, modelPath, downloadKey, progressCallback
55
57
  const existingStats = await fsPromises.stat(modelPath);
56
58
  startOffset = existingStats.size;
57
59
  downloadedBytes = startOffset;
58
- console.log(`📥 Resuming download from byte ${startOffset}`);
60
+ logger.info(`📥 Resuming download from byte ${startOffset}`);
59
61
  }
60
62
  catch {
61
- console.log(`📥 Starting fresh download`);
63
+ logger.info(`📥 Starting fresh download`);
62
64
  }
63
65
  // Prepare headers for resume if needed
64
66
  const headers = {
@@ -77,7 +79,7 @@ async function performHttpDownload(url, modelPath, downloadKey, progressCallback
77
79
  if (!response.ok) {
78
80
  // Check if it's a 416 (Range Not Satisfiable) - file already complete
79
81
  if (response.status === 416 && startOffset > 0) {
80
- console.log(`✅ File already completely downloaded`);
82
+ logger.info(`✅ File already completely downloaded`);
81
83
  // Send 100% progress for already complete file
82
84
  if (progressCallback) {
83
85
  progressCallback({
@@ -92,7 +94,7 @@ async function performHttpDownload(url, modelPath, downloadKey, progressCallback
92
94
  }
93
95
  // Check if server doesn't support range requests
94
96
  if (response.status === 200 && startOffset > 0) {
95
- console.log(`⚠️ Server doesn't support resume, starting fresh download`);
97
+ logger.warn(`⚠️ Server doesn't support resume, starting fresh download`);
96
98
  startOffset = 0;
97
99
  downloadedBytes = 0;
98
100
  // Retry without Range header
@@ -131,7 +133,7 @@ async function performHttpDownload(url, modelPath, downloadKey, progressCallback
131
133
  // For fresh downloads
132
134
  totalBytes = contentLength ? parseInt(contentLength) : 0;
133
135
  }
134
- console.log(`📏 Total size: ${totalBytes} bytes (${(totalBytes / 1024 / 1024).toFixed(2)} MB)`);
136
+ logger.info(`📏 Total size: ${totalBytes} bytes (${(totalBytes / 1024 / 1024).toFixed(2)} MB)`);
135
137
  // Create write stream (append if resuming)
136
138
  const writeStreamOptions = startOffset > 0 && response.status === 206 ? { flags: "a" } : {};
137
139
  const writeStream = fs.createWriteStream(modelPath, writeStreamOptions);
@@ -174,7 +176,7 @@ async function performHttpDownload(url, modelPath, downloadKey, progressCallback
174
176
  signal.addEventListener("abort", abortHandler);
175
177
  }
176
178
  writeStream.on("finish", () => {
177
- console.log(`✅ Model downloaded successfully to ${modelPath}`);
179
+ logger.info(`✅ Model downloaded successfully to ${modelPath}`);
178
180
  if (signal) {
179
181
  signal.removeEventListener("abort", abortHandler);
180
182
  }
@@ -216,7 +218,7 @@ async function performHttpDownload(url, modelPath, downloadKey, progressCallback
216
218
  // Close the write stream
217
219
  await new Promise((resolve, reject) => {
218
220
  writeStream.end(() => {
219
- console.log(`✅ Model downloaded successfully to ${modelPath}`);
221
+ logger.info(`✅ Model downloaded successfully to ${modelPath}`);
220
222
  resolve();
221
223
  });
222
224
  writeStream.on("error", reject);
@@ -262,7 +264,7 @@ async function performHttpDownload(url, modelPath, downloadKey, progressCallback
262
264
  // Close the write stream
263
265
  await new Promise((resolve, reject) => {
264
266
  writeStream.end(() => {
265
- console.log(`✅ Model downloaded successfully to ${modelPath}`);
267
+ logger.info(`✅ Model downloaded successfully to ${modelPath}`);
266
268
  resolve();
267
269
  });
268
270
  writeStream.on("error", reject);
@@ -275,7 +277,7 @@ async function performHttpDownload(url, modelPath, downloadKey, progressCallback
275
277
  }
276
278
  catch (error) {
277
279
  writeStream.destroy();
278
- console.error("Error during download:", error instanceof Error ? error.message : String(error));
280
+ logger.error("Error during download:", error instanceof Error ? error.message : String(error));
279
281
  throw error instanceof Error ? error : new Error(String(error));
280
282
  }
281
283
  }
@@ -284,7 +286,7 @@ export async function downloadModelFromHttp(url, progressCallback) {
284
286
  // Check if already downloading
285
287
  const existing = getActiveDownload(downloadKey);
286
288
  if (existing) {
287
- console.log(`📥 Reusing existing download for: ${downloadKey}`);
289
+ logger.info(`📥 Reusing existing download for: ${downloadKey}`);
288
290
  return existing.promise;
289
291
  }
290
292
  const cacheDir = getModelsCacheDir();
@@ -336,21 +338,21 @@ export async function downloadModelFromHttp(url, progressCallback) {
336
338
  return modelPath;
337
339
  }
338
340
  catch (error) {
339
- console.error("❌ Error downloading model:", error instanceof Error ? error.message : String(error));
341
+ logger.error("❌ Error downloading model:", error instanceof Error ? error.message : String(error));
340
342
  // Check if we should delete the partial file (clearCache was requested)
341
343
  if (error instanceof Error && error.message === "Download cancelled") {
342
344
  if (shouldClearCache(downloadKey)) {
343
- console.log("🗑️ Clearing cache - deleting partial file");
345
+ logger.info("🗑️ Clearing cache - deleting partial file");
344
346
  try {
345
347
  await fsPromises.unlink(modelPath);
346
- console.log(`✅ Deleted partial file: ${modelPath}`);
348
+ logger.info(`✅ Deleted partial file: ${modelPath}`);
347
349
  }
348
350
  catch {
349
351
  // Ignore cleanup errors
350
352
  }
351
353
  }
352
354
  else {
353
- console.log("📥 Download paused - partial file preserved for resume");
355
+ logger.info("📥 Download paused - partial file preserved for resume");
354
356
  }
355
357
  clearClearCacheFlag(downloadKey);
356
358
  }
@@ -11,6 +11,8 @@ import { getModelBySrc } from "../../../../models/hyperdrive/index.js";
11
11
  import { getActiveDownload, registerDownload, unregisterDownload, createHyperdriveDownloadKey, shouldClearCache, clearClearCacheFlag, } from "./download-manager.js";
12
12
  import { getSDKConfig } from "../../../bare/registry/config-registry.js";
13
13
  import { FileNotFoundError, ChecksumValidationFailedError, DownloadCancelledError, HyperdriveDownloadFailedError, ModelLoadFailedError, NoBlobFoundError, } from "../../../../utils/errors-server.js";
14
+ import { getServerLogger } from "../../../../logging/index.js";
15
+ const logger = getServerLogger();
14
16
  function getCorestoreDir(hyperdriveKey) {
15
17
  return path.join(getEnv().HOME_DIR, ".qvac", "corestore", hyperdriveKey);
16
18
  }
@@ -33,7 +35,7 @@ async function setupHyperdrive(hyperdriveKey, corestoreDir) {
33
35
  const swarm = new Hyperswarm(swarmOptions);
34
36
  const doneFindingPeers = drive.findingPeers();
35
37
  swarm.on("connection", (connection) => {
36
- console.log(`🤝 Connected to peer for hyperdrive download`);
38
+ logger.debug(`🤝 Connected to peer for hyperdrive download`);
37
39
  drive.replicate(connection);
38
40
  });
39
41
  swarm.join(drive.discoveryKey, { server: false, client: true });
@@ -41,7 +43,7 @@ async function setupHyperdrive(hyperdriveKey, corestoreDir) {
41
43
  return { corestore, drive, swarm, corestoreDir };
42
44
  }
43
45
  async function cleanupHyperdrive(setup) {
44
- console.log("🧹 Cleaning up hyperdrive setup");
46
+ logger.debug("🧹 Cleaning up hyperdrive setup");
45
47
  if (!setup.swarm.suspended) {
46
48
  try {
47
49
  await setup.swarm.suspend();
@@ -55,12 +57,12 @@ async function cleanupHyperdrive(setup) {
55
57
  await setup.corestore.close();
56
58
  }
57
59
  export async function deleteCorestoreDirectory(corestoreDir) {
58
- console.log(`🗑️ DELETING corestore directory... ${corestoreDir}`);
60
+ logger.info(`🗑️ DELETING corestore directory... ${corestoreDir}`);
59
61
  try {
60
62
  await fsPromises.rm(corestoreDir, { recursive: true, force: true });
61
63
  }
62
64
  catch (e) {
63
- console.error(`Error deleting corestore directory: ${e instanceof Error ? e.message : String(e)}`);
65
+ logger.error(`Error deleting corestore directory: ${e instanceof Error ? e.message : String(e)}`);
64
66
  }
65
67
  }
66
68
  async function findFileInHyperdrive(drive, modelFileName) {
@@ -148,7 +150,7 @@ async function validateCachedFile(modelPath, modelFileName, expectedSize, expect
148
150
  // For hyperdrive: only validate if file is complete
149
151
  // Partial files are ignored - corestore state is the source of truth for resume
150
152
  if (localSize === expectedSize) {
151
- console.log(`✅ Model cached with correct size: ${modelPath}`);
153
+ logger.info(`✅ Model cached with correct size: ${modelPath}`);
152
154
  // Always validate checksum if provided, even when size matches
153
155
  if (expectedChecksum && expectedChecksum.length === 64) {
154
156
  const checksum = await calculateFileChecksum(modelPath);
@@ -156,7 +158,7 @@ async function validateCachedFile(modelPath, modelFileName, expectedSize, expect
156
158
  throw new ChecksumValidationFailedError(`${modelFileName}. Expected: ${expectedChecksum}. Actual: ${checksum}. File may be corrupted`);
157
159
  }
158
160
  }
159
- console.log(`✅ Model already cached and size validated: ${modelPath}`);
161
+ logger.info(`✅ Model already cached and size validated: ${modelPath}`);
160
162
  return modelPath;
161
163
  }
162
164
  // File exists but incomplete - will be overwritten during download
@@ -173,10 +175,10 @@ async function downloadSingleFileToFilesystem(modelPath, modelFileName, hyperdri
173
175
  if (signal?.aborted) {
174
176
  throw new DownloadCancelledError();
175
177
  }
176
- console.log(`Downloading model from hyperdrive ${hyperdriveKey} to ${modelPath}`);
178
+ logger.info(`Downloading model from hyperdrive ${hyperdriveKey} to ${modelPath}`);
177
179
  const setup = await setupHyperdrive(hyperdriveKey, corestoreDir);
178
180
  const cleanup = () => {
179
- console.log("🛑 Aborting hyperdrive download...");
181
+ logger.info("🛑 Aborting hyperdrive download...");
180
182
  setup.swarm.suspended = true;
181
183
  setup.swarm.suspend().catch(() => {
182
184
  // Ignore errors during emergency suspend
@@ -192,7 +194,7 @@ async function downloadSingleFileToFilesystem(modelPath, modelFileName, hyperdri
192
194
  : undefined;
193
195
  await downloadAndValidateFile(setup.drive, modelFileName, modelPath, 0, // Size will be determined from drive
194
196
  expectedChecksum, progressContext, signal);
195
- console.log(`✅ Model downloaded successfully to ${modelPath}`);
197
+ logger.info(`✅ Model downloaded successfully to ${modelPath}`);
196
198
  // Send final 100% progress update
197
199
  if (progressCallback) {
198
200
  try {
@@ -215,7 +217,7 @@ async function downloadSingleFileToFilesystem(modelPath, modelFileName, hyperdri
215
217
  }
216
218
  }
217
219
  catch (error) {
218
- console.error("❌ Error during hyperdrive download:", error instanceof Error ? error.message : String(error));
220
+ logger.error("❌ Error during hyperdrive download:", error instanceof Error ? error.message : String(error));
219
221
  // Preserve cancellation errors
220
222
  if (error instanceof Error && error.message === "Download cancelled") {
221
223
  throw error;
@@ -319,7 +321,7 @@ async function downloadAndValidateFile(drive, sourceFileName, targetFilePath, ex
319
321
  }
320
322
  }
321
323
  else if (!expectedChecksum) {
322
- console.log(`⚠️ No checksum available for validation`);
324
+ logger.warn(`⚠️ No checksum available for validation`);
323
325
  }
324
326
  }
325
327
  catch (error) {
@@ -368,11 +370,11 @@ async function downloadShardedFilesToFilesystem(hyperdriveKey, firstShardFileNam
368
370
  const shardDir = getShardedModelCacheDir(hyperdriveKey);
369
371
  const allFiles = shardMetadata.map((s) => s.filename);
370
372
  const numberedShardCount = shardInfo.totalShards;
371
- console.log(`Downloading sharded model with ${numberedShardCount} numbered shards + ${allFiles.length - numberedShardCount} companion files to ${shardDir}`);
373
+ logger.info(`Downloading sharded model with ${numberedShardCount} numbered shards + ${allFiles.length - numberedShardCount} companion files to ${shardDir}`);
372
374
  // Check which files need to be downloaded
373
375
  const invalidIndices = await checkShardCompleteness(hyperdriveKey, allFiles, shardMetadata);
374
376
  if (invalidIndices.length === 0) {
375
- console.log(`✅ All ${allFiles.length} files already downloaded and validated`);
377
+ logger.info(`✅ All ${allFiles.length} files already downloaded and validated`);
376
378
  if (progressCallback) {
377
379
  const overallTotal = shardMetadata.reduce((sum, shard) => sum + shard.expectedSize, 0);
378
380
  const lastFile = allFiles[allFiles.length - 1];
@@ -394,12 +396,12 @@ async function downloadShardedFilesToFilesystem(hyperdriveKey, firstShardFileNam
394
396
  }
395
397
  return getShardPath(hyperdriveKey, allFiles[0]);
396
398
  }
397
- console.log(`📥 Need to download ${invalidIndices.length} of ${allFiles.length} files`);
399
+ logger.info(`📥 Need to download ${invalidIndices.length} of ${allFiles.length} files`);
398
400
  // Setup hyperdrive once for all shards
399
401
  const corestoreDir = getCorestoreDir(hyperdriveKey);
400
402
  const setup = await setupHyperdrive(hyperdriveKey, corestoreDir);
401
403
  const cleanup = () => {
402
- console.log("🛑 Aborting sharded hyperdrive download...");
404
+ logger.info("🛑 Aborting sharded hyperdrive download...");
403
405
  setup.swarm.suspended = true;
404
406
  setup.swarm.suspend().catch(() => {
405
407
  // Ignore errors during emergency suspend
@@ -420,7 +422,7 @@ async function downloadShardedFilesToFilesystem(hyperdriveKey, firstShardFileNam
420
422
  const filePath = getShardPath(hyperdriveKey, file);
421
423
  // Skip if already valid
422
424
  if (!invalidIndices.includes(i)) {
423
- console.log(`✅ File ${i + 1}/${allFiles.length} already valid: ${file}`);
425
+ logger.debug(`✅ File ${i + 1}/${allFiles.length} already valid: ${file}`);
424
426
  overallDownloaded += fileMeta.expectedSize;
425
427
  // Report progress for skipped files
426
428
  if (progressCallback) {
@@ -442,7 +444,7 @@ async function downloadShardedFilesToFilesystem(hyperdriveKey, firstShardFileNam
442
444
  }
443
445
  continue;
444
446
  }
445
- console.log(`📥 Downloading file ${i + 1}/${allFiles.length}: ${file}`);
447
+ logger.info(`📥 Downloading file ${i + 1}/${allFiles.length}: ${file}`);
446
448
  const progressContext = progressCallback
447
449
  ? {
448
450
  downloadKey: createHyperdriveDownloadKey(hyperdriveKey, firstShardFileName),
@@ -460,7 +462,7 @@ async function downloadShardedFilesToFilesystem(hyperdriveKey, firstShardFileNam
460
462
  if (signal?.aborted) {
461
463
  throw new DownloadCancelledError();
462
464
  }
463
- console.log(`✅ File ${i + 1}/${allFiles.length} downloaded and validated`);
465
+ logger.info(`✅ File ${i + 1}/${allFiles.length} downloaded and validated`);
464
466
  overallDownloaded += fileMeta.expectedSize;
465
467
  }
466
468
  if (progressCallback && overallDownloaded === overallTotal) {
@@ -487,7 +489,7 @@ async function downloadShardedFilesToFilesystem(hyperdriveKey, firstShardFileNam
487
489
  }
488
490
  }
489
491
  catch (error) {
490
- console.error("❌ Error during sharded hyperdrive download:", error instanceof Error ? error.message : String(error));
492
+ logger.error("❌ Error during sharded hyperdrive download:", error instanceof Error ? error.message : String(error));
491
493
  // Preserve cancellation errors
492
494
  if (error instanceof Error && error.message === "Download cancelled") {
493
495
  throw error;
@@ -6,6 +6,8 @@ import path from "bare-path";
6
6
  import { downloadModelFromHttp } from "./http.js";
7
7
  import { downloadModelFromHyperdrive } from "./hyperdrive.js";
8
8
  import { ModelLoadFailedError, ModelNotFoundError, SeedingNotSupportedError, } from "../../../../utils/errors-server.js";
9
+ import { getServerLogger } from "../../../../logging/index.js";
10
+ const logger = getServerLogger();
9
11
  /**
10
12
  * Resolves a local file path or cached file
11
13
  */
@@ -20,14 +22,14 @@ async function resolveLocalOrCachedFile(modelIdOrPath) {
20
22
  const cachedPath = path.join(cacheDir, modelIdOrPath);
21
23
  try {
22
24
  await fsPromises.access(cachedPath);
23
- console.log(`Loading cached model: ${cachedPath}`);
25
+ logger.info(`Loading cached model: ${cachedPath}`);
24
26
  return cachedPath;
25
27
  }
26
28
  catch {
27
29
  // Try as local file in current directory
28
30
  try {
29
31
  await fsPromises.access(modelIdOrPath);
30
- console.log(`Loading local file: ${modelIdOrPath}`);
32
+ logger.info(`Loading local file: ${modelIdOrPath}`);
31
33
  return modelIdOrPath;
32
34
  }
33
35
  catch {
@@ -57,13 +59,13 @@ export async function resolveModelPath(modelSrc, progressCallback, seed) {
57
59
  // Check if it's an HTTP/HTTPS URL
58
60
  if (actualModelSrc.startsWith("http://") ||
59
61
  actualModelSrc.startsWith("https://")) {
60
- console.log(`Loading from HTTP URL: ${actualModelSrc}`);
62
+ logger.info(`Loading from HTTP URL: ${actualModelSrc}`);
61
63
  actualPath = await downloadModelFromHttp(actualModelSrc, progressCallback);
62
- console.log(`Loaded Model to ${actualPath}`);
64
+ logger.info(`Loaded Model to ${actualPath}`);
63
65
  }
64
66
  else if (hyperdriveKey) {
65
67
  // Direct hyperdrive loading
66
- console.log(`Loading from hyperdrive: ${hyperdriveKey}`);
68
+ logger.info(`Loading from hyperdrive: ${hyperdriveKey}`);
67
69
  actualPath = await downloadModelFromHyperdrive(hyperdriveKey, actualModelSrc, seed, progressCallback);
68
70
  }
69
71
  else if (actualModelSrc.includes("/") || actualModelSrc.includes("\\")) {
@@ -1,3 +1,3 @@
1
- import type { LoadModelRequest, LoadModelResponse, ModelProgressUpdate } from "../../../schemas/index";
2
- export declare function handleLoadModelDelegated(request: LoadModelRequest, progressCallback?: (update: ModelProgressUpdate) => void): Promise<LoadModelResponse>;
1
+ import type { LoadModelSrcRequest, LoadModelResponse, ModelProgressUpdate } from "../../../schemas/index";
2
+ export declare function handleLoadModelDelegated(request: LoadModelSrcRequest, progressCallback?: (update: ModelProgressUpdate) => void): Promise<LoadModelResponse>;
3
3
  //# sourceMappingURL=load-model-delegated.d.ts.map
@@ -4,6 +4,8 @@ import { getRPC } from "../../bare/delegate-rpc-client.js";
4
4
  import { send, stream } from "../../../client/rpc/rpc-client.js";
5
5
  import { handleLoadModel } from "./load-model/index.js";
6
6
  import { ModelLoadFailedError, DelegateNoFinalResponseError, } from "../../../utils/errors-server.js";
7
+ import { getServerLogger } from "../../../logging/index.js";
8
+ const logger = getServerLogger();
7
9
  export async function handleLoadModelDelegated(request, progressCallback) {
8
10
  if (!request.delegate) {
9
11
  throw new ModelLoadFailedError("Delegate information is required for delegated load model");
@@ -11,7 +13,7 @@ export async function handleLoadModelDelegated(request, progressCallback) {
11
13
  const { delegate } = request;
12
14
  const { topic, providerPublicKey, timeout, fallbackToLocal } = delegate;
13
15
  try {
14
- console.log(`📤 Sending delegated loadModel request to provider: ${providerPublicKey}${timeout ? `, timeout: ${timeout}ms` : ""}`);
16
+ logger.info(`📤 Sending delegated loadModel request to provider: ${providerPublicKey}${timeout ? `, timeout: ${timeout}ms` : ""}`);
15
17
  // Create RPC instance for this HyperSwarm peer
16
18
  const rpc = await getRPC(topic, providerPublicKey, { timeout });
17
19
  // Strip out the delegate field to avoid infinite delegation
@@ -20,7 +22,7 @@ export async function handleLoadModelDelegated(request, progressCallback) {
20
22
  let finalResponse;
21
23
  if (request.withProgress) {
22
24
  // Use streaming for progress updates
23
- console.log("📊 Using streaming mode for loadModel with progress");
25
+ logger.debug("📊 Using streaming mode for loadModel with progress");
24
26
  const responseStream = stream(providerRequest, rpc, timeout ? { timeout } : {});
25
27
  for await (const response of responseStream) {
26
28
  if (response.type === "modelProgress") {
@@ -40,11 +42,11 @@ export async function handleLoadModelDelegated(request, progressCallback) {
40
42
  }
41
43
  else {
42
44
  // Use simple send for non-progress requests
43
- console.log("📤 Using simple send mode for loadModel");
45
+ logger.debug("📤 Using simple send mode for loadModel");
44
46
  finalResponse = (await send(providerRequest, rpc, timeout ? { timeout } : {}));
45
47
  }
46
48
  if (!finalResponse || !finalResponse.success) {
47
- console.error("Provider failed to load model:", finalResponse?.error);
49
+ logger.error("Provider failed to load model:", finalResponse?.error);
48
50
  return {
49
51
  type: "loadModel",
50
52
  success: false,
@@ -62,7 +64,7 @@ export async function handleLoadModelDelegated(request, progressCallback) {
62
64
  delegateOptions.timeout = timeout;
63
65
  }
64
66
  registerModel(modelId, delegateOptions);
65
- console.log(`✅ Delegated model registered: ${modelId} -> provider: ${providerPublicKey}`);
67
+ logger.info(`✅ Delegated model registered: ${modelId} -> provider: ${providerPublicKey}`);
66
68
  return {
67
69
  type: "loadModel",
68
70
  success: true,
@@ -70,16 +72,16 @@ export async function handleLoadModelDelegated(request, progressCallback) {
70
72
  };
71
73
  }
72
74
  catch (error) {
73
- console.error("Error in delegated load model:", error);
75
+ logger.error("Error in delegated load model:", error);
74
76
  if (fallbackToLocal) {
75
- console.log("🔄 Fallback to local model loading enabled, attempting local load...");
77
+ logger.info("🔄 Fallback to local model loading enabled, attempting local load...");
76
78
  try {
77
79
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
78
80
  const { delegate: _, ...localRequest } = request;
79
81
  return await handleLoadModel(localRequest, progressCallback);
80
82
  }
81
83
  catch (localError) {
82
- console.error("❌ Local fallback also failed:", localError);
84
+ logger.error("❌ Local fallback also failed:", localError);
83
85
  return {
84
86
  type: "loadModel",
85
87
  success: false,
@@ -1,8 +1,16 @@
1
1
  import { loadModel } from "../../bare/addons/index.js";
2
2
  import { resolveModelPath } from "./load-model/resolve.js";
3
- import { generateShortHash } from "../../utils/index.js";
4
- import { TTSConfigModelRequiredError, ESpeakDataPathRequiredError, } from "../../../utils/errors-server.js";
3
+ import { getModelEntry, updateModelConfig, } from "../../bare/registry/model-registry.js";
4
+ import { generateShortHash, transformConfigForReload } from "../../utils/index.js";
5
+ import { TTSConfigModelRequiredError, ESpeakDataPathRequiredError, ConfigReloadNotSupportedError, ModelTypeMismatchError, ModelIsDelegatedError, ModelNotFoundError, } from "../../../utils/errors-server.js";
6
+ import { getServerLogger } from "../../../logging/index.js";
7
+ const logger = getServerLogger();
5
8
  export async function handleLoadModel(request, progressCallback) {
9
+ // Handle reload config
10
+ if (isReloadConfigRequest(request)) {
11
+ return handleConfigReload(request);
12
+ }
13
+ // Handle load new model from source
6
14
  const { modelSrc, modelName, seed, projectionModelSrc, vadModelSrc, configSrc, } = request;
7
15
  const eSpeakDataPath = request.modelType === "tts"
8
16
  ? request.eSpeakDataPath
@@ -49,7 +57,48 @@ export async function handleLoadModel(request, progressCallback) {
49
57
  };
50
58
  }
51
59
  catch (error) {
52
- console.error("Error loading model:", error);
60
+ logger.error("Error loading model:", error);
61
+ return {
62
+ type: "loadModel",
63
+ success: false,
64
+ error: error instanceof Error ? error.message : "Unknown error",
65
+ };
66
+ }
67
+ }
68
+ async function handleConfigReload(request) {
69
+ const { modelId, modelType, modelConfig } = request;
70
+ try {
71
+ const entry = getModelEntry(modelId);
72
+ if (!entry) {
73
+ throw new ModelNotFoundError(modelId);
74
+ }
75
+ if (entry.isDelegated) {
76
+ throw new ModelIsDelegatedError(modelId);
77
+ }
78
+ const storedModelType = entry.local.modelType;
79
+ if (storedModelType !== modelType) {
80
+ throw new ModelTypeMismatchError(storedModelType, modelType);
81
+ }
82
+ const model = entry.local.model;
83
+ const currentConfig = entry.local.config;
84
+ if (typeof model.reload !== "function") {
85
+ throw new ConfigReloadNotSupportedError(modelId);
86
+ }
87
+ const mergedConfig = {
88
+ ...currentConfig,
89
+ ...modelConfig,
90
+ };
91
+ const reloadConfig = transformConfigForReload(storedModelType, mergedConfig);
92
+ await model.reload(reloadConfig);
93
+ updateModelConfig(modelId, mergedConfig);
94
+ return {
95
+ type: "loadModel",
96
+ success: true,
97
+ modelId,
98
+ };
99
+ }
100
+ catch (error) {
101
+ logger.error("Error reloading config:", error);
53
102
  return {
54
103
  type: "loadModel",
55
104
  success: false,
@@ -57,3 +106,6 @@ export async function handleLoadModel(request, progressCallback) {
57
106
  };
58
107
  }
59
108
  }
109
+ function isReloadConfigRequest(request) {
110
+ return "modelId" in request && !("modelSrc" in request);
111
+ }
@@ -1,12 +1,12 @@
1
1
  import { registerLoggingStream, unregisterLoggingStream, } from "../../bare/registry/logging-stream-registry.js";
2
2
  export async function* handleLoggingStream(request) {
3
- const { modelId } = request;
3
+ const { id } = request;
4
4
  const logQueue = [];
5
5
  let pendingResolve = null;
6
6
  const streamHandler = (level, namespace, message) => {
7
7
  const logResponse = {
8
8
  type: "loggingStream",
9
- modelId,
9
+ id,
10
10
  level: level,
11
11
  namespace,
12
12
  message,
@@ -19,7 +19,7 @@ export async function* handleLoggingStream(request) {
19
19
  resolve();
20
20
  }
21
21
  };
22
- registerLoggingStream(modelId, streamHandler);
22
+ registerLoggingStream(id, streamHandler);
23
23
  try {
24
24
  while (true) {
25
25
  while (logQueue.length > 0) {
@@ -32,6 +32,6 @@ export async function* handleLoggingStream(request) {
32
32
  }
33
33
  }
34
34
  finally {
35
- unregisterLoggingStream(modelId, streamHandler);
35
+ unregisterLoggingStream(id, streamHandler);
36
36
  }
37
37
  }
@@ -1,25 +1,27 @@
1
1
  import RPC from "bare-rpc";
2
2
  import { createRpcProxy } from "./proxy.js";
3
+ import { getServerLogger } from "../../../../logging/index.js";
4
+ const logger = getServerLogger();
3
5
  export function setupConnectionHandlers(swarm) {
4
- console.log("👂 Setting up connection listener...");
6
+ logger.debug("👂 Setting up connection listener...");
5
7
  swarm.on("close", () => {
6
- console.log("🔗 Connection closed!");
8
+ logger.debug("🔗 Connection closed!");
7
9
  });
8
10
  swarm.on("connection", (conn) => {
9
- console.log("🔗 Connection event triggered!");
11
+ logger.debug("🔗 Connection event triggered!");
10
12
  const peerPubkey = conn.remotePublicKey?.toString("hex");
11
- console.log(`📡 New connection established from: ${peerPubkey?.substring(0, 16)}...`);
12
- console.log("🔐 Full peer public key:", peerPubkey);
13
+ logger.info(`📡 New connection established from: ${peerPubkey?.substring(0, 16)}...`);
14
+ logger.debug("🔐 Full peer public key:", peerPubkey);
13
15
  // Create RPC instance for this connection (as server)
14
- console.log("⚙️ Creating RPC instance for connection...");
16
+ logger.debug("⚙️ Creating RPC instance for connection...");
15
17
  new RPC(conn, createRpcProxy());
16
- console.log("✅ RPC instance created successfully");
18
+ logger.debug("✅ RPC instance created successfully");
17
19
  conn.on("close", () => {
18
- console.log(`🔌 Connection closed for peer: ${peerPubkey?.substring(0, 16)}`);
20
+ logger.debug(`🔌 Connection closed for peer: ${peerPubkey?.substring(0, 16)}`);
19
21
  });
20
22
  conn.on("error", (err) => {
21
- console.error(`❌ Connection error for peer ${peerPubkey?.substring(0, 16)}:`, err);
23
+ logger.error(`❌ Connection error for peer ${peerPubkey?.substring(0, 16)}:`, err);
22
24
  });
23
25
  });
24
- console.log("✅ Connection listener set up");
26
+ logger.debug("✅ Connection listener set up");
25
27
  }