@qvac/sdk 0.7.1 → 0.8.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 (218) hide show
  1. package/NOTICE +57 -331
  2. package/README.md +2 -2
  3. package/bare-imports.json +9 -0
  4. package/dist/client/api/completion-stream.d.ts +2 -1
  5. package/dist/client/api/completion-stream.js +2 -1
  6. package/dist/client/api/download-asset.d.ts +3 -2
  7. package/dist/client/api/download-asset.js +4 -3
  8. package/dist/client/api/embed.d.ts +5 -2
  9. package/dist/client/api/embed.js +2 -2
  10. package/dist/client/api/get-model-info.d.ts +1 -1
  11. package/dist/client/api/invoke-plugin.d.ts +3 -2
  12. package/dist/client/api/invoke-plugin.js +4 -4
  13. package/dist/client/api/load-model.d.ts +12 -10
  14. package/dist/client/api/load-model.js +3 -3
  15. package/dist/client/api/rag.d.ts +10 -10
  16. package/dist/client/api/rag.js +21 -21
  17. package/dist/client/api/text-to-speech.d.ts +2 -2
  18. package/dist/client/api/text-to-speech.js +3 -3
  19. package/dist/client/api/transcribe.d.ts +5 -3
  20. package/dist/client/api/transcribe.js +6 -4
  21. package/dist/client/api/translate.d.ts +2 -2
  22. package/dist/client/api/translate.js +3 -3
  23. package/dist/client/rpc/node-rpc-client.d.ts +2 -7
  24. package/dist/client/rpc/node-rpc-client.js +2 -39
  25. package/dist/client/rpc/profiling/index.d.ts +2 -0
  26. package/dist/client/rpc/profiling/index.js +1 -0
  27. package/dist/client/rpc/profiling/profiler.d.ts +27 -0
  28. package/dist/client/rpc/profiling/profiler.js +139 -0
  29. package/dist/client/rpc/rpc-client.d.ts +2 -2
  30. package/dist/client/rpc/rpc-client.js +174 -12
  31. package/dist/examples/delegated-inference/consumer-profiled.d.ts +2 -0
  32. package/dist/examples/delegated-inference/consumer-profiled.js +67 -0
  33. package/dist/examples/llamacpp-multimodal.js +1 -1
  34. package/dist/examples/parallel-download.js +45 -13
  35. package/dist/examples/profiling/basic.d.ts +2 -0
  36. package/dist/examples/profiling/basic.js +71 -0
  37. package/dist/examples/profiling/per-call.d.ts +2 -0
  38. package/dist/examples/profiling/per-call.js +30 -0
  39. package/dist/examples/transcription/parakeet-ctc-filesystem.d.ts +2 -0
  40. package/dist/examples/transcription/parakeet-ctc-filesystem.js +40 -0
  41. package/dist/examples/transcription/parakeet-microphone-record.d.ts +2 -0
  42. package/dist/examples/transcription/parakeet-microphone-record.js +95 -0
  43. package/dist/examples/transcription/parakeet-sortformer.d.ts +2 -0
  44. package/dist/examples/transcription/parakeet-sortformer.js +115 -0
  45. package/dist/examples/transcription/parakeet-tdt-filesystem.d.ts +2 -0
  46. package/dist/examples/transcription/parakeet-tdt-filesystem.js +44 -0
  47. package/dist/examples/translation/translation-bergamot-pivot.d.ts +2 -0
  48. package/dist/examples/translation/translation-bergamot-pivot.js +73 -0
  49. package/dist/examples/translation/translation-llm-afriquegemma.d.ts +2 -0
  50. package/dist/examples/translation/translation-llm-afriquegemma.js +39 -0
  51. package/dist/index.d.ts +3 -1
  52. package/dist/index.js +2 -0
  53. package/dist/logging/index.d.ts +1 -1
  54. package/dist/logging/index.js +1 -1
  55. package/dist/logging/namespaces.d.ts +3 -9
  56. package/dist/logging/namespaces.js +2 -8
  57. package/dist/logging/registry.js +15 -1
  58. package/dist/models/registry/models.d.ts +1606 -245
  59. package/dist/models/registry/models.js +2127 -721
  60. package/dist/models/update-models/codegen.js +2 -2
  61. package/dist/models/update-models/history.d.ts +11 -0
  62. package/dist/models/update-models/history.js +24 -5
  63. package/dist/models/update-models/index.js +17 -16
  64. package/dist/models/update-models/naming.js +56 -0
  65. package/dist/profiling/aggregator.d.ts +15 -0
  66. package/dist/profiling/aggregator.js +100 -0
  67. package/dist/profiling/clock.d.ts +12 -0
  68. package/dist/profiling/clock.js +51 -0
  69. package/dist/profiling/controller.d.ts +33 -0
  70. package/dist/profiling/controller.js +123 -0
  71. package/dist/profiling/envelope.d.ts +10 -0
  72. package/dist/profiling/envelope.js +36 -0
  73. package/dist/profiling/events.d.ts +20 -0
  74. package/dist/profiling/events.js +37 -0
  75. package/dist/profiling/exporters.d.ts +10 -0
  76. package/dist/profiling/exporters.js +236 -0
  77. package/dist/profiling/index.d.ts +36 -0
  78. package/dist/profiling/index.js +31 -0
  79. package/dist/profiling/ring-buffer.d.ts +19 -0
  80. package/dist/profiling/ring-buffer.js +83 -0
  81. package/dist/profiling/types.d.ts +47 -0
  82. package/dist/profiling/types.js +1 -0
  83. package/dist/schemas/common.d.ts +1888 -133
  84. package/dist/schemas/common.js +2 -0
  85. package/dist/schemas/completion-stream.d.ts +31 -0
  86. package/dist/schemas/completion-stream.js +13 -0
  87. package/dist/schemas/download-asset.d.ts +14 -3
  88. package/dist/schemas/download-asset.js +3 -1
  89. package/dist/schemas/engine-addon-map.js +9 -6
  90. package/dist/schemas/get-model-info.d.ts +2 -0
  91. package/dist/schemas/get-model-info.js +1 -0
  92. package/dist/schemas/index.d.ts +2 -1
  93. package/dist/schemas/index.js +2 -1
  94. package/dist/schemas/llamacpp-config.d.ts +140 -14
  95. package/dist/schemas/llamacpp-config.js +11 -7
  96. package/dist/schemas/load-model.d.ts +9649 -2515
  97. package/dist/schemas/load-model.js +142 -182
  98. package/dist/schemas/model-src-utils.d.ts +10 -2
  99. package/dist/schemas/model-types.d.ts +19 -1
  100. package/dist/schemas/model-types.js +11 -0
  101. package/dist/schemas/ocr.d.ts +37 -0
  102. package/dist/schemas/ocr.js +5 -0
  103. package/dist/schemas/plugin.d.ts +51 -5
  104. package/dist/schemas/plugin.js +26 -0
  105. package/dist/schemas/profiling.d.ts +105 -0
  106. package/dist/schemas/profiling.js +66 -0
  107. package/dist/schemas/registry.d.ts +18 -0
  108. package/dist/schemas/registry.js +2 -0
  109. package/dist/schemas/reload-config.d.ts +126 -6
  110. package/dist/schemas/reload-config.js +1 -1
  111. package/dist/schemas/sdk-config.d.ts +2280 -24
  112. package/dist/schemas/sdk-config.js +6 -1
  113. package/dist/schemas/sdk-errors-client.d.ts +1 -0
  114. package/dist/schemas/sdk-errors-client.js +7 -0
  115. package/dist/schemas/sdk-errors-server.d.ts +3 -0
  116. package/dist/schemas/sdk-errors-server.js +15 -0
  117. package/dist/schemas/text-to-speech.d.ts +90 -68
  118. package/dist/schemas/text-to-speech.js +16 -33
  119. package/dist/schemas/transcription-config.d.ts +383 -0
  120. package/dist/schemas/{whispercpp-config.js → transcription-config.js} +29 -1
  121. package/dist/schemas/translation-config.d.ts +463 -8
  122. package/dist/schemas/translation-config.js +35 -2
  123. package/dist/server/bare/delegate-rpc-client.js +11 -1
  124. package/dist/server/bare/ops/load-model.d.ts +7 -1
  125. package/dist/server/bare/ops/load-model.js +41 -42
  126. package/dist/server/bare/ops/transcribe.d.ts +3 -0
  127. package/dist/server/bare/ops/transcribe.js +75 -0
  128. package/dist/server/bare/ops/translate.d.ts +2 -0
  129. package/dist/server/bare/ops/translate.js +12 -4
  130. package/dist/server/bare/plugins/index.d.ts +1 -0
  131. package/dist/server/bare/plugins/index.js +1 -0
  132. package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stream.d.ts +2 -1
  133. package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stream.js +8 -6
  134. package/dist/server/bare/plugins/llamacpp-completion/plugin.d.ts +108 -3
  135. package/dist/server/bare/plugins/llamacpp-completion/plugin.js +19 -6
  136. package/dist/server/bare/plugins/llamacpp-embedding/plugin.d.ts +32 -2
  137. package/dist/server/bare/plugins/llamacpp-embedding/plugin.js +31 -17
  138. package/dist/server/bare/plugins/nmtcpp-translation/plugin.d.ts +325 -3
  139. package/dist/server/bare/plugins/nmtcpp-translation/plugin.js +117 -10
  140. package/dist/server/bare/plugins/onnx-ocr/plugin.d.ts +50 -2
  141. package/dist/server/bare/plugins/onnx-ocr/plugin.js +46 -5
  142. package/dist/server/bare/plugins/onnx-tts/plugin.d.ts +351 -4
  143. package/dist/server/bare/plugins/onnx-tts/plugin.js +81 -61
  144. package/dist/server/bare/plugins/parakeet-transcription/plugin.d.ts +317 -0
  145. package/dist/server/bare/plugins/parakeet-transcription/plugin.js +154 -0
  146. package/dist/server/bare/plugins/whispercpp-transcription/plugin.d.ts +209 -3
  147. package/dist/server/bare/plugins/whispercpp-transcription/plugin.js +21 -9
  148. package/dist/server/bare/rag-hyperdb/rag-workspace-manager.js +2 -2
  149. package/dist/server/bare/registry/model-config-utils.js +3 -1
  150. package/dist/server/bare/utils/audio-input.d.ts +10 -0
  151. package/dist/server/bare/utils/audio-input.js +33 -0
  152. package/dist/server/error-handlers.d.ts +3 -2
  153. package/dist/server/error-handlers.js +11 -8
  154. package/dist/server/plugins/registry.js +5 -1
  155. package/dist/server/rpc/delegate-transport.d.ts +11 -3
  156. package/dist/server/rpc/delegate-transport.js +158 -3
  157. package/dist/server/rpc/handle-request.js +43 -4
  158. package/dist/server/rpc/handler-registry.js +7 -1
  159. package/dist/server/rpc/handler-utils.d.ts +5 -4
  160. package/dist/server/rpc/handler-utils.js +72 -31
  161. package/dist/server/rpc/handlers/completion-stream-delegated.d.ts +3 -1
  162. package/dist/server/rpc/handlers/completion-stream-delegated.js +11 -2
  163. package/dist/server/rpc/handlers/download-asset.js +55 -3
  164. package/dist/server/rpc/handlers/load-model/download-stats.d.ts +6 -0
  165. package/dist/server/rpc/handlers/load-model/download-stats.js +87 -0
  166. package/dist/server/rpc/handlers/load-model/handler.js +108 -123
  167. package/dist/server/rpc/handlers/load-model/http.d.ts +2 -1
  168. package/dist/server/rpc/handlers/load-model/http.js +21 -5
  169. package/dist/server/rpc/handlers/load-model/hyperdrive.d.ts +2 -1
  170. package/dist/server/rpc/handlers/load-model/hyperdrive.js +19 -14
  171. package/dist/server/rpc/handlers/load-model/registry.d.ts +2 -1
  172. package/dist/server/rpc/handlers/load-model/registry.js +123 -130
  173. package/dist/server/rpc/handlers/load-model/resolve.d.ts +2 -0
  174. package/dist/server/rpc/handlers/load-model/resolve.js +55 -22
  175. package/dist/server/rpc/handlers/load-model/types.d.ts +29 -0
  176. package/dist/server/rpc/handlers/load-model/types.js +1 -0
  177. package/dist/server/rpc/handlers/load-model-delegated.d.ts +5 -1
  178. package/dist/server/rpc/handlers/load-model-delegated.js +35 -7
  179. package/dist/server/rpc/handlers/plugin-dispatch.js +15 -10
  180. package/dist/server/rpc/handlers/plugin-invoke.js +56 -51
  181. package/dist/server/rpc/handlers/rag.js +24 -0
  182. package/dist/server/rpc/handlers/unload-model-delegated.d.ts +3 -0
  183. package/dist/server/rpc/handlers/unload-model-delegated.js +32 -0
  184. package/dist/server/rpc/profiling/context.d.ts +18 -0
  185. package/dist/server/rpc/profiling/context.js +38 -0
  186. package/dist/server/rpc/profiling/delegation-profiler.d.ts +32 -0
  187. package/dist/server/rpc/profiling/delegation-profiler.js +154 -0
  188. package/dist/server/rpc/profiling/index.d.ts +5 -0
  189. package/dist/server/rpc/profiling/index.js +4 -0
  190. package/dist/server/rpc/profiling/operation-metrics.d.ts +25 -0
  191. package/dist/server/rpc/profiling/operation-metrics.js +199 -0
  192. package/dist/server/rpc/profiling/operation-wrappers.d.ts +18 -0
  193. package/dist/server/rpc/profiling/operation-wrappers.js +124 -0
  194. package/dist/server/rpc/profiling/profiler.d.ts +13 -0
  195. package/dist/server/rpc/profiling/profiler.js +97 -0
  196. package/dist/server/utils/cache.d.ts +2 -1
  197. package/dist/server/utils/cache.js +5 -1
  198. package/dist/server/utils/checksum.d.ts +2 -0
  199. package/dist/server/utils/checksum.js +7 -0
  200. package/dist/server/utils/formatting.d.ts +6 -0
  201. package/dist/server/utils/formatting.js +35 -0
  202. package/dist/server/worker.js +2 -1
  203. package/dist/utils/errors-client.d.ts +3 -0
  204. package/dist/utils/errors-client.js +6 -0
  205. package/dist/utils/errors-server.d.ts +9 -0
  206. package/dist/utils/errors-server.js +15 -0
  207. package/dist/utils/global-singleton.d.ts +2 -0
  208. package/dist/utils/global-singleton.js +10 -0
  209. package/package.json +13 -16
  210. package/dist/schemas/whispercpp-config.d.ts +0 -70
  211. package/dist/server/bare/plugins/whispercpp-transcription/ops/transcribe-stream.d.ts +0 -3
  212. package/dist/server/bare/plugins/whispercpp-transcription/ops/transcribe-stream.js +0 -81
  213. /package/dist/examples/{whispercpp-filesystem.d.ts → transcription/whispercpp-filesystem.d.ts} +0 -0
  214. /package/dist/examples/{whispercpp-filesystem.js → transcription/whispercpp-filesystem.js} +0 -0
  215. /package/dist/examples/{whispercpp-microphone-record.d.ts → transcription/whispercpp-microphone-record.d.ts} +0 -0
  216. /package/dist/examples/{whispercpp-microphone-record.js → transcription/whispercpp-microphone-record.js} +0 -0
  217. /package/dist/examples/{whispercpp-prompt.d.ts → transcription/whispercpp-prompt.d.ts} +0 -0
  218. /package/dist/examples/{whispercpp-prompt.js → transcription/whispercpp-prompt.js} +0 -0
@@ -1,112 +1,135 @@
1
- import { normalizeModelType, ModelType } from "../../../../schemas/index.js";
2
- import { hyperdriveUrlSchema } from "../../../../schemas/load-model.js";
1
+ import { normalizeModelType, PROFILING_KEY, OPERATION_EVENT_KEY, } from "../../../../schemas/index.js";
3
2
  import { loadModel } from "../../../bare/ops/load-model.js";
4
- import { resolveModelPath } from "./resolve.js";
3
+ import { resolveModelPath, resolveModelPathWithStats, } from "./resolve.js";
4
+ import { nowMs, generateProfileId } from "../../../../profiling/clock.js";
5
5
  import { getModelEntry, updateModelConfig, } from "../../../bare/registry/model-registry.js";
6
- import { generateShortHash, transformConfigForReload } from "../../../utils/index.js";
7
- import { ConfigReloadNotSupportedError, ModelTypeMismatchError, ModelIsDelegatedError, ModelNotFoundError, } from "../../../../utils/errors-server.js";
6
+ import { generateShortHash, canonicalConfigString, transformConfigForReload, } from "../../../utils/index.js";
7
+ import { ConfigReloadNotSupportedError, ModelTypeMismatchError, ModelIsDelegatedError, ModelNotFoundError, ModelLoadFailedError, PluginLoadConfigValidationFailedError, PluginNotFoundError, } from "../../../../utils/errors-server.js";
8
8
  import { getServerLogger } from "../../../../logging/index.js";
9
- import { OCR_CRAFT_DETECTOR } from "../../../../models/registry/index.js";
10
9
  import { getPlugin } from "../../../plugins/index.js";
11
10
  const logger = getServerLogger();
12
- const OCR_DETECTOR_FILENAME = "detector_craft.onnx";
11
+ // ---------------------------------------------------------------------------
12
+ // Handler
13
+ // ---------------------------------------------------------------------------
13
14
  export async function handleLoadModel(request, progressCallback) {
14
- // Handle reload config
15
15
  if (isReloadConfigRequest(request)) {
16
16
  return handleConfigReload(request);
17
17
  }
18
- // Handle load new model from source
19
- const { modelSrc, modelName, seed, projectionModelSrc, vadModelSrc } = request;
18
+ const { modelSrc, modelName, seed } = request;
20
19
  const canonicalModelType = normalizeModelType(request.modelType);
21
- const srcVocabSrc = canonicalModelType === ModelType.nmtcppTranslation
22
- ? request.srcVocabSrc
23
- : undefined;
24
- const dstVocabSrc = canonicalModelType === ModelType.nmtcppTranslation
25
- ? request.dstVocabSrc
26
- : undefined;
27
- const detectorModelSrc = canonicalModelType === ModelType.onnxOcr
28
- ? request.detectorModelSrc
29
- : undefined;
20
+ const profilingMeta = request[PROFILING_KEY];
21
+ const profilingEnabled = profilingMeta?.enabled !== false && !!profilingMeta;
30
22
  try {
31
- const modelPath = await resolveModelPath(modelSrc, progressCallback, seed);
32
- let projectionModelPath;
33
- if (projectionModelSrc) {
34
- projectionModelPath = await resolveModelPath(projectionModelSrc, progressCallback, seed);
23
+ const plugin = getPlugin(canonicalModelType);
24
+ if (!plugin) {
25
+ throw new PluginNotFoundError(canonicalModelType);
35
26
  }
36
- let vadModelPath;
37
- if (vadModelSrc) {
38
- vadModelPath = await resolveModelPath(vadModelSrc, progressCallback, seed);
27
+ let resolvedModelConfig = (request.modelConfig ?? {});
28
+ const parseResult = plugin.loadConfigSchema.safeParse(resolvedModelConfig);
29
+ if (!parseResult.success) {
30
+ const details = parseResult.error.issues
31
+ .map((i) => `${String(i.path.join("."))}: ${i.message}`)
32
+ .join(", ");
33
+ throw new PluginLoadConfigValidationFailedError(canonicalModelType, details);
39
34
  }
40
- // For OCR models: use provided detectorModelSrc or auto-derive
41
- let detectorModelPath;
42
- if (canonicalModelType === ModelType.onnxOcr) {
43
- if (detectorModelSrc) {
44
- detectorModelPath = await resolveModelPath(detectorModelSrc, progressCallback, seed);
45
- }
46
- else if (modelSrc.startsWith("pear://")) {
47
- const { key } = hyperdriveUrlSchema.parse(modelSrc);
48
- const derivedDetectorSrc = `pear://${key}/${OCR_DETECTOR_FILENAME}`;
49
- detectorModelPath = await resolveModelPath(derivedDetectorSrc, progressCallback, seed);
50
- }
51
- else if (modelSrc.startsWith("registry://")) {
52
- detectorModelPath = await resolveModelPath(OCR_CRAFT_DETECTOR, progressCallback, seed);
53
- }
35
+ resolvedModelConfig = parseResult.data;
36
+ const totalLoadStart = profilingEnabled ? nowMs() : 0;
37
+ let resolveResult;
38
+ let resolvedModelPath;
39
+ if (profilingEnabled) {
40
+ resolveResult = await resolveModelPathWithStats(modelSrc, progressCallback, seed);
41
+ resolvedModelPath = resolveResult.path;
54
42
  }
55
- // For Bergamot models, resolve vocabulary sources to local paths
56
- if (canonicalModelType === ModelType.nmtcppTranslation &&
57
- request.modelConfig) {
58
- const nmtConfig = request.modelConfig;
59
- if (nmtConfig.engine === "Bergamot") {
60
- let resolvedSrcVocabSrc = srcVocabSrc;
61
- let resolvedDstVocabSrc = dstVocabSrc;
62
- if (!srcVocabSrc || !dstVocabSrc) {
63
- const derivedVocabSrcs = modelSrc.startsWith("pear://")
64
- ? deriveBergamotVocabSources(modelSrc)
65
- : modelSrc.startsWith("registry://")
66
- ? deriveBergamotRegistryVocabSources(modelSrc)
67
- : null;
68
- if (derivedVocabSrcs) {
69
- resolvedSrcVocabSrc = srcVocabSrc ?? derivedVocabSrcs.srcVocabSrc;
70
- resolvedDstVocabSrc = dstVocabSrc ?? derivedVocabSrcs.dstVocabSrc;
71
- }
72
- }
73
- if (resolvedSrcVocabSrc) {
74
- nmtConfig.srcVocabPath = await resolveModelPath(resolvedSrcVocabSrc, progressCallback, seed);
75
- }
76
- if (resolvedDstVocabSrc) {
77
- nmtConfig.dstVocabPath = await resolveModelPath(resolvedDstVocabSrc, progressCallback, seed);
78
- }
79
- }
43
+ else {
44
+ resolvedModelPath = await resolveModelPath(modelSrc, progressCallback, seed);
80
45
  }
81
- // Use plugin's resolveConfig hook if available to resolve model sources
82
- let resolvedModelConfig = request.modelConfig;
83
- const plugin = getPlugin(canonicalModelType);
84
- if (plugin?.resolveConfig && resolvedModelConfig) {
85
- const resolve = (src) => resolveModelPath(src, progressCallback, seed);
86
- resolvedModelConfig = await plugin.resolveConfig(resolvedModelConfig, resolve);
46
+ let pluginArtifacts = {};
47
+ if (plugin.resolveConfig) {
48
+ const ctx = {
49
+ resolveModelPath: (src) => resolveModelPath(src, progressCallback, seed),
50
+ modelSrc,
51
+ modelType: canonicalModelType,
52
+ ...(modelName !== undefined && { modelName }),
53
+ };
54
+ const result = await plugin.resolveConfig(resolvedModelConfig, ctx);
55
+ resolvedModelConfig = result.config;
56
+ if (result.artifacts) {
57
+ pluginArtifacts = result.artifacts;
58
+ }
87
59
  }
88
- // Generate hash-based modelId from modelConfig (includes all sources for TTS)
89
- const configStr = JSON.stringify(request.modelConfig, Object.keys(request.modelConfig).sort());
60
+ const configStr = canonicalConfigString(request.modelConfig);
90
61
  const modelHashInput = `${request.modelType}:${modelSrc}:${configStr}`;
91
62
  const modelId = generateShortHash(modelHashInput);
92
- const loadModelOptions = {
93
- ...request,
94
- modelConfig: resolvedModelConfig,
95
- };
96
- await loadModel({
63
+ if ("modelPath" in pluginArtifacts) {
64
+ logger.warn("Plugin returned 'modelPath' artifact which was overridden by core");
65
+ }
66
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
67
+ const { modelPath: _, ...artifacts } = pluginArtifacts;
68
+ if (!resolvedModelPath) {
69
+ throw new ModelLoadFailedError("modelPath resolution failed");
70
+ }
71
+ const loadResult = await loadModel({
97
72
  modelId,
98
- modelPath,
99
- options: loadModelOptions,
100
- projectionModelPath,
101
- vadModelPath,
102
- detectorModelPath,
73
+ modelPath: resolvedModelPath,
74
+ options: {
75
+ ...request,
76
+ modelType: canonicalModelType,
77
+ modelConfig: resolvedModelConfig,
78
+ },
79
+ artifacts: Object.keys(artifacts).length > 0 ? artifacts : undefined,
103
80
  modelName,
104
- });
105
- return {
81
+ }, profilingEnabled ? { collectTiming: true } : undefined);
82
+ const response = {
106
83
  type: "loadModel",
107
84
  success: true,
108
85
  modelId,
109
86
  };
87
+ if (profilingEnabled) {
88
+ const totalLoadTimeMs = nowMs() - totalLoadStart;
89
+ const profileId = profilingMeta?.id ?? generateProfileId();
90
+ const gauges = {
91
+ totalLoadTime: totalLoadTimeMs,
92
+ };
93
+ if (loadResult.timing?.modelInitializationTimeMs !== undefined) {
94
+ gauges["modelInitializationTime"] =
95
+ loadResult.timing.modelInitializationTimeMs;
96
+ }
97
+ if (resolveResult?.downloadStats) {
98
+ const ds = resolveResult.downloadStats;
99
+ if (ds.downloadTimeMs !== undefined) {
100
+ gauges["downloadTime"] = ds.downloadTimeMs;
101
+ }
102
+ if (ds.totalBytesDownloaded !== undefined) {
103
+ gauges["totalBytesDownloaded"] = ds.totalBytesDownloaded;
104
+ }
105
+ if (ds.downloadSpeedBps !== undefined) {
106
+ gauges["downloadSpeedBps"] = ds.downloadSpeedBps;
107
+ }
108
+ if (ds.checksumValidationTimeMs !== undefined) {
109
+ gauges["checksumValidationTime"] = ds.checksumValidationTimeMs;
110
+ }
111
+ }
112
+ const tags = {};
113
+ if (canonicalModelType) {
114
+ tags["modelType"] = canonicalModelType;
115
+ }
116
+ if (resolveResult?.sourceType) {
117
+ tags["sourceType"] = resolveResult.sourceType;
118
+ }
119
+ if (resolveResult?.downloadStats?.cacheHit !== undefined) {
120
+ tags["cacheHit"] = resolveResult.downloadStats.cacheHit ? "true" : "false";
121
+ }
122
+ const operationEvent = {
123
+ op: "loadModel",
124
+ kind: "handler",
125
+ ms: totalLoadTimeMs,
126
+ profileId,
127
+ gauges: Object.keys(gauges).length > 0 ? gauges : undefined,
128
+ tags: Object.keys(tags).length > 0 ? tags : undefined,
129
+ };
130
+ response[OPERATION_EVENT_KEY] = operationEvent;
131
+ }
132
+ return response;
110
133
  }
111
134
  catch (error) {
112
135
  logger.error("Error loading model:", error);
@@ -162,41 +185,3 @@ async function handleConfigReload(request) {
162
185
  function isReloadConfigRequest(request) {
163
186
  return "modelId" in request && !("modelSrc" in request);
164
187
  }
165
- const BERGAMOT_CJK_LANG_PAIRS = ["enja", "enko", "enzh"];
166
- function deriveBergamotVocabSources(modelSrc) {
167
- const match = modelSrc.match(/^pear:\/\/([a-f0-9]+)\/model\.([a-z]+)\.intgemm\.alphas\.bin$/);
168
- if (!match || !match[1] || !match[2])
169
- return null;
170
- const key = match[1];
171
- const langPair = match[2];
172
- if (BERGAMOT_CJK_LANG_PAIRS.includes(langPair)) {
173
- return {
174
- srcVocabSrc: `pear://${key}/srcvocab.${langPair}.spm`,
175
- dstVocabSrc: `pear://${key}/trgvocab.${langPair}.spm`,
176
- };
177
- }
178
- const sharedVocab = `pear://${key}/vocab.${langPair}.spm`;
179
- return {
180
- srcVocabSrc: sharedVocab,
181
- dstVocabSrc: sharedVocab,
182
- };
183
- }
184
- function deriveBergamotRegistryVocabSources(modelSrc) {
185
- // registry://s3/path/to/model.enfr.intgemm.alphas.bin
186
- const match = modelSrc.match(/^(registry:\/\/.+\/)model\.([a-z]+)\.intgemm\.alphas\.bin$/);
187
- if (!match || !match[1] || !match[2])
188
- return null;
189
- const basePath = match[1];
190
- const langPair = match[2];
191
- if (BERGAMOT_CJK_LANG_PAIRS.includes(langPair)) {
192
- return {
193
- srcVocabSrc: `${basePath}srcvocab.${langPair}.spm`,
194
- dstVocabSrc: `${basePath}trgvocab.${langPair}.spm`,
195
- };
196
- }
197
- const sharedVocab = `${basePath}vocab.${langPair}.spm`;
198
- return {
199
- srcVocabSrc: sharedVocab,
200
- dstVocabSrc: sharedVocab,
201
- };
202
- }
@@ -1,3 +1,4 @@
1
1
  import type { ModelProgressUpdate } from "../../../../schemas/index";
2
- export declare function downloadModelFromHttp(url: string, progressCallback?: (progress: ModelProgressUpdate) => void): Promise<string>;
2
+ import type { DownloadMetricsHooks } from "./types";
3
+ export declare function downloadModelFromHttp(url: string, progressCallback?: (progress: ModelProgressUpdate) => void, hooks?: DownloadMetricsHooks): Promise<string>;
3
4
  //# sourceMappingURL=http.d.ts.map
@@ -314,19 +314,20 @@ async function performHttpDownload(url, modelPath, downloadKey, progressCallback
314
314
  throw error instanceof Error ? error : new Error(String(error));
315
315
  }
316
316
  }
317
- export async function downloadModelFromHttp(url, progressCallback) {
317
+ export async function downloadModelFromHttp(url, progressCallback, hooks) {
318
318
  const filename = extractFilenameFromUrl(url);
319
319
  if (isArchiveUrl(url)) {
320
- return downloadShardedModelFromArchive(url, progressCallback);
320
+ return downloadShardedModelFromArchive(url, progressCallback, hooks);
321
321
  }
322
322
  const shardInfo = detectShardedModel(filename);
323
323
  if (shardInfo.isSharded && shardInfo.totalShards) {
324
- return downloadShardedModelFromHttp(url, progressCallback);
324
+ return downloadShardedModelFromHttp(url, progressCallback, hooks);
325
325
  }
326
326
  const downloadKey = createHttpDownloadKey(url);
327
327
  const existing = getActiveDownload(downloadKey);
328
328
  if (existing) {
329
329
  logger.info(`📥 Reusing existing download for: ${downloadKey}`);
330
+ hooks?.markCacheMiss();
330
331
  return existing.promise;
331
332
  }
332
333
  const cacheDir = getModelsCacheDir();
@@ -339,6 +340,7 @@ export async function downloadModelFromHttp(url, progressCallback) {
339
340
  // Check if already cached
340
341
  const cachedPath = await validateCachedFile(modelPath, url, abortController.signal);
341
342
  if (cachedPath) {
343
+ hooks?.markCacheHit();
342
344
  if (progressCallback) {
343
345
  try {
344
346
  const stats = await fsPromises.stat(cachedPath);
@@ -360,6 +362,7 @@ export async function downloadModelFromHttp(url, progressCallback) {
360
362
  return cachedPath;
361
363
  }
362
364
  // Download the file
365
+ hooks?.markCacheMiss();
363
366
  await performHttpDownload(url, modelPath, downloadKey, progressCallback, abortController.signal);
364
367
  // Send final 100% progress update
365
368
  if (progressCallback) {
@@ -426,7 +429,7 @@ export async function downloadModelFromHttp(url, progressCallback) {
426
429
  registerDownload(downloadKey, downloadEntry);
427
430
  return downloadPromise;
428
431
  }
429
- async function downloadShardedModelFromHttp(shardUrl, progressCallback) {
432
+ async function downloadShardedModelFromHttp(shardUrl, progressCallback, hooks) {
430
433
  const config = getSDKConfig();
431
434
  const concurrency = config.httpDownloadConcurrency ?? DEFAULT_CONCURRENCY;
432
435
  const { shardUrls: shardInfos, cacheKey } = parsePatternBasedShardUrl(shardUrl);
@@ -435,6 +438,7 @@ async function downloadShardedModelFromHttp(shardUrl, progressCallback) {
435
438
  const existing = getActiveDownload(downloadKey);
436
439
  if (existing) {
437
440
  logger.info(`📥 Reusing existing sharded download for: ${downloadKey}`);
441
+ hooks?.markCacheMiss();
438
442
  return existing.promise;
439
443
  }
440
444
  const abortController = new AbortController();
@@ -483,6 +487,12 @@ async function downloadShardedModelFromHttp(shardUrl, progressCallback) {
483
487
  }
484
488
  }
485
489
  logger.info(`📥 ${shardsToDownload.length} of ${shardInfos.length} shards need downloading`);
490
+ if (shardsToDownload.length === 0) {
491
+ hooks?.markCacheHit();
492
+ }
493
+ else {
494
+ hooks?.markCacheMiss();
495
+ }
486
496
  await downloadShardsWithConcurrency(shardsToDownload, shardStates, concurrency, abortController.signal, downloadKey, overallTotal, progressCallback);
487
497
  logger.info(`✅ All ${shardInfos.length} shards downloaded successfully`);
488
498
  await extractTensorsFromShards(shardDir, shardInfos[0].filename);
@@ -523,7 +533,7 @@ async function downloadShardedModelFromHttp(shardUrl, progressCallback) {
523
533
  });
524
534
  return downloadPromise;
525
535
  }
526
- async function downloadShardedModelFromArchive(archiveUrl, progressCallback) {
536
+ async function downloadShardedModelFromArchive(archiveUrl, progressCallback, hooks) {
527
537
  const filename = extractFilenameFromUrl(archiveUrl);
528
538
  const sourceHash = generateShortHash(archiveUrl);
529
539
  const downloadKey = `http-archive:${sourceHash}`;
@@ -531,6 +541,7 @@ async function downloadShardedModelFromArchive(archiveUrl, progressCallback) {
531
541
  const existing = getActiveDownload(downloadKey);
532
542
  if (existing) {
533
543
  logger.info(`📥 Reusing existing archive download for: ${downloadKey}`);
544
+ hooks?.markCacheMiss();
534
545
  return existing.promise;
535
546
  }
536
547
  const abortController = new AbortController();
@@ -542,12 +553,14 @@ async function downloadShardedModelFromArchive(archiveUrl, progressCallback) {
542
553
  const files = await fsPromises.readdir(extractDir);
543
554
  const shardedFile = files.find((f) => detectShardedModel(String(f)).isSharded);
544
555
  if (!shardedFile) {
556
+ hooks?.markCacheMiss();
545
557
  return downloadAndExtractArchive();
546
558
  }
547
559
  const shardFilename = String(shardedFile);
548
560
  const allShardsExist = await checkAllShardsExist(extractDir, shardFilename);
549
561
  if (!allShardsExist) {
550
562
  logger.warn(`⚠️ Incomplete shards found, re-downloading archive`);
563
+ hooks?.markCacheMiss();
551
564
  return downloadAndExtractArchive();
552
565
  }
553
566
  const shardFilenames = generateShardFilenames(shardFilename);
@@ -555,6 +568,7 @@ async function downloadShardedModelFromArchive(archiveUrl, progressCallback) {
555
568
  const isComplete = await validateShardedModelCache(extractDir, shardFilename);
556
569
  if (isComplete) {
557
570
  logger.info(`✅ Archive already extracted: ${extractDir}`);
571
+ hooks?.markCacheHit();
558
572
  if (progressCallback) {
559
573
  progressCallback({
560
574
  type: "modelProgress",
@@ -570,6 +584,7 @@ async function downloadShardedModelFromArchive(archiveUrl, progressCallback) {
570
584
  try {
571
585
  await extractTensorsFromShards(extractDir, shardFilename);
572
586
  logger.info(`✅ Tensors extracted successfully`);
587
+ hooks?.markCacheHit();
573
588
  if (progressCallback) {
574
589
  progressCallback({
575
590
  type: "modelProgress",
@@ -585,6 +600,7 @@ async function downloadShardedModelFromArchive(archiveUrl, progressCallback) {
585
600
  logger.warn(`Failed to extract tensors, will re-download archive`, {
586
601
  error,
587
602
  });
603
+ hooks?.markCacheMiss();
588
604
  return downloadAndExtractArchive();
589
605
  }
590
606
  }
@@ -1,4 +1,5 @@
1
1
  import type { ModelProgressUpdate } from "../../../../schemas/index";
2
+ import type { DownloadMetricsHooks } from "./types";
2
3
  export declare function deleteCorestoreDirectory(corestoreDir: string): Promise<void>;
3
- export declare function downloadModelFromHyperdrive(hyperdriveKey: string, modelFileName: string, seed?: boolean, progressCallback?: (progress: ModelProgressUpdate) => void, expectedChecksum?: string): Promise<string>;
4
+ export declare function downloadModelFromHyperdrive(hyperdriveKey: string, modelFileName: string, seed?: boolean, progressCallback?: (progress: ModelProgressUpdate) => void, hooks?: DownloadMetricsHooks, expectedChecksum?: string): Promise<string>;
4
5
  //# sourceMappingURL=hyperdrive.d.ts.map
@@ -6,7 +6,7 @@ import Hyperdrive from "hyperdrive";
6
6
  import {} from "bare-stream";
7
7
  import { AbortController } from "bare-abort-controller";
8
8
  import { getEnv } from "../../../env.js";
9
- import { getModelsCacheDir, generateShortHash, detectShardedModel, getShardedModelCacheDir, getShardPath, checkShardCompleteness, calculateFileChecksum, extractTensorsFromShards, calculatePercentage, } from "../../../utils/index.js";
9
+ import { getModelsCacheDir, generateShortHash, detectShardedModel, getShardedModelCacheDir, getShardPath, checkShardCompleteness, measureChecksum, extractTensorsFromShards, calculatePercentage, } from "../../../utils/index.js";
10
10
  import { getModelBySrc } from "../../../../models/registry/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";
@@ -142,7 +142,7 @@ async function validateFileExistence(drive, file) {
142
142
  totalBytes,
143
143
  };
144
144
  }
145
- async function validateCachedFile(modelPath, modelFileName, expectedSize, expectedChecksum) {
145
+ async function validateCachedFile(modelPath, modelFileName, expectedSize, expectedChecksum, hooks) {
146
146
  try {
147
147
  await fsPromises.access(modelPath);
148
148
  const localStats = await fsPromises.stat(modelPath);
@@ -153,7 +153,7 @@ async function validateCachedFile(modelPath, modelFileName, expectedSize, expect
153
153
  logger.info(`✅ Model cached with correct size: ${modelPath}`);
154
154
  // Always validate checksum if provided, even when size matches
155
155
  if (expectedChecksum && expectedChecksum.length === 64) {
156
- const checksum = await calculateFileChecksum(modelPath);
156
+ const checksum = await measureChecksum(modelPath, hooks);
157
157
  if (checksum !== expectedChecksum) {
158
158
  throw new ChecksumValidationFailedError(`${modelFileName}. Expected: ${expectedChecksum}. Actual: ${checksum}. File may be corrupted`);
159
159
  }
@@ -170,7 +170,7 @@ async function validateCachedFile(modelPath, modelFileName, expectedSize, expect
170
170
  return null;
171
171
  }
172
172
  }
173
- async function downloadSingleFileToFilesystem(modelPath, modelFileName, hyperdriveKey, corestoreDir, downloadKey, expectedChecksum, progressCallback, seed, signal) {
173
+ async function downloadSingleFileToFilesystem(modelPath, modelFileName, hyperdriveKey, corestoreDir, downloadKey, expectedChecksum, progressCallback, seed, signal, hooks) {
174
174
  // Check if already aborted
175
175
  if (signal?.aborted) {
176
176
  throw new DownloadCancelledError();
@@ -194,7 +194,7 @@ async function downloadSingleFileToFilesystem(modelPath, modelFileName, hyperdri
194
194
  }
195
195
  : undefined;
196
196
  await downloadAndValidateFile(setup.drive, modelFileName, modelPath, 0, // Size will be determined from drive
197
- expectedChecksum, progressContext, signal);
197
+ expectedChecksum, progressContext, signal, hooks);
198
198
  logger.info(`✅ Model downloaded successfully to ${modelPath}`);
199
199
  // Send final 100% progress update
200
200
  if (progressCallback) {
@@ -244,7 +244,7 @@ async function downloadSingleFileToFilesystem(modelPath, modelFileName, hyperdri
244
244
  clearClearCacheFlag(downloadKey);
245
245
  }
246
246
  }
247
- async function downloadAndValidateFile(drive, sourceFileName, targetFilePath, expectedSize, expectedChecksum, progressContext, signal) {
247
+ async function downloadAndValidateFile(drive, sourceFileName, targetFilePath, expectedSize, expectedChecksum, progressContext, signal, hooks) {
248
248
  const { entry, blobs, targetPath, blocksDownloaded, totalBlocks, totalBytes, } = await validateFileExistence(drive, sourceFileName);
249
249
  const blob = entry?.value?.blob;
250
250
  if (!blob) {
@@ -316,7 +316,7 @@ async function downloadAndValidateFile(drive, sourceFileName, targetFilePath, ex
316
316
  }
317
317
  // Validate checksum
318
318
  if (expectedChecksum && expectedChecksum.length === 64) {
319
- const checksum = await calculateFileChecksum(targetFilePath);
319
+ const checksum = await measureChecksum(targetFilePath, hooks);
320
320
  if (checksum !== expectedChecksum) {
321
321
  await fsPromises.unlink(targetFilePath);
322
322
  throw new ChecksumValidationFailedError(`${path.basename(targetFilePath)}. Expected: ${expectedChecksum}. Actual: ${checksum}`);
@@ -361,7 +361,7 @@ function createManagedDownload(downloadKey, hyperdriveKey, modelFileName, downlo
361
361
  registerDownload(downloadKey, downloadEntry);
362
362
  return downloadPromise;
363
363
  }
364
- async function downloadShardedFilesToFilesystem(hyperdriveKey, firstShardFileName, shardMetadata, progressCallback, seed, signal) {
364
+ async function downloadShardedFilesToFilesystem(hyperdriveKey, firstShardFileName, shardMetadata, progressCallback, seed, signal, hooks) {
365
365
  if (signal?.aborted) {
366
366
  throw new DownloadCancelledError();
367
367
  }
@@ -374,9 +374,10 @@ async function downloadShardedFilesToFilesystem(hyperdriveKey, firstShardFileNam
374
374
  const numberedShardCount = shardInfo.totalShards;
375
375
  logger.info(`Downloading sharded model with ${numberedShardCount} numbered shards + ${allFiles.length - numberedShardCount} companion files to ${shardDir}`);
376
376
  // Check which files need to be downloaded
377
- const invalidIndices = await checkShardCompleteness(hyperdriveKey, allFiles, shardMetadata);
377
+ const invalidIndices = await checkShardCompleteness(hyperdriveKey, allFiles, shardMetadata, hooks ? (ms) => hooks.addChecksumValidationTimeMs(ms) : undefined);
378
378
  if (invalidIndices.length === 0) {
379
379
  logger.info(`✅ All ${allFiles.length} files already downloaded and validated`);
380
+ hooks?.markCacheHit();
380
381
  if (progressCallback) {
381
382
  const overallTotal = shardMetadata.reduce((sum, shard) => sum + shard.expectedSize, 0);
382
383
  const lastFile = allFiles[allFiles.length - 1];
@@ -400,6 +401,7 @@ async function downloadShardedFilesToFilesystem(hyperdriveKey, firstShardFileNam
400
401
  return getShardPath(hyperdriveKey, allFiles[0]);
401
402
  }
402
403
  logger.info(`📥 Need to download ${invalidIndices.length} of ${allFiles.length} files`);
404
+ hooks?.markCacheMiss();
403
405
  // Setup hyperdrive once for all shards
404
406
  const corestoreDir = getCorestoreDir(hyperdriveKey);
405
407
  const setup = await setupHyperdrive(hyperdriveKey, corestoreDir);
@@ -462,7 +464,7 @@ async function downloadShardedFilesToFilesystem(hyperdriveKey, firstShardFileNam
462
464
  },
463
465
  }
464
466
  : undefined;
465
- await downloadAndValidateFile(setup.drive, file, filePath, fileMeta.expectedSize, fileMeta.sha256Checksum, progressContext, signal);
467
+ await downloadAndValidateFile(setup.drive, file, filePath, fileMeta.expectedSize, fileMeta.sha256Checksum, progressContext, signal, hooks);
466
468
  if (signal?.aborted) {
467
469
  throw new DownloadCancelledError();
468
470
  }
@@ -516,17 +518,18 @@ async function downloadShardedFilesToFilesystem(hyperdriveKey, firstShardFileNam
516
518
  }
517
519
  return getShardPath(hyperdriveKey, allFiles[0]);
518
520
  }
519
- export async function downloadModelFromHyperdrive(hyperdriveKey, modelFileName, seed, progressCallback, expectedChecksum) {
521
+ export async function downloadModelFromHyperdrive(hyperdriveKey, modelFileName, seed, progressCallback, hooks, expectedChecksum) {
520
522
  const downloadKey = createHyperdriveDownloadKey(hyperdriveKey, modelFileName);
521
523
  // Check if already downloading
522
524
  const existing = getActiveDownload(downloadKey);
523
525
  if (existing) {
526
+ hooks?.markCacheMiss();
524
527
  return existing.promise;
525
528
  }
526
529
  const shardInfo = detectShardedModel(modelFileName);
527
530
  const model = getModelBySrc(modelFileName, hyperdriveKey);
528
531
  if (shardInfo.isSharded && model?.shardMetadata) {
529
- return createManagedDownload(downloadKey, hyperdriveKey, modelFileName, (signal) => downloadShardedFilesToFilesystem(hyperdriveKey, modelFileName, model.shardMetadata, progressCallback, seed, signal), progressCallback);
532
+ return createManagedDownload(downloadKey, hyperdriveKey, modelFileName, (signal) => downloadShardedFilesToFilesystem(hyperdriveKey, modelFileName, model.shardMetadata, progressCallback, seed, signal, hooks), progressCallback);
530
533
  }
531
534
  // Non-sharded model download
532
535
  const corestoreDir = getCorestoreDir(hyperdriveKey);
@@ -535,8 +538,9 @@ export async function downloadModelFromHyperdrive(hyperdriveKey, modelFileName,
535
538
  const modelPath = path.join(cacheDir, `${sourceHash}_${modelFileName}`);
536
539
  // First, check if we already have a valid cached file (only if we have model metadata)
537
540
  if (model) {
538
- const cachedPath = await validateCachedFile(modelPath, modelFileName, model.expectedSize, expectedChecksum || model.sha256Checksum);
541
+ const cachedPath = await validateCachedFile(modelPath, modelFileName, model.expectedSize, expectedChecksum || model.sha256Checksum, hooks);
539
542
  if (cachedPath) {
543
+ hooks?.markCacheHit();
540
544
  if (progressCallback) {
541
545
  progressCallback({
542
546
  type: "modelProgress",
@@ -553,9 +557,10 @@ export async function downloadModelFromHyperdrive(hyperdriveKey, modelFileName,
553
557
  return cachedPath;
554
558
  }
555
559
  }
560
+ hooks?.markCacheMiss();
556
561
  return createManagedDownload(downloadKey, hyperdriveKey, modelFileName, async (signal) => {
557
562
  const checksumToValidate = expectedChecksum || model?.sha256Checksum || "";
558
- await downloadSingleFileToFilesystem(modelPath, modelFileName, hyperdriveKey, corestoreDir, downloadKey, checksumToValidate, progressCallback, seed, signal);
563
+ await downloadSingleFileToFilesystem(modelPath, modelFileName, hyperdriveKey, corestoreDir, downloadKey, checksumToValidate, progressCallback, seed, signal, hooks);
559
564
  return modelPath;
560
565
  }, progressCallback);
561
566
  }
@@ -1,4 +1,5 @@
1
1
  import type { ModelProgressUpdate } from "../../../../schemas/index";
2
+ import type { DownloadMetricsHooks } from "./types";
2
3
  /**
3
4
  * Download a model from the QVAC Registry.
4
5
  *
@@ -6,5 +7,5 @@ import type { ModelProgressUpdate } from "../../../../schemas/index";
6
7
  * skips the registry metadata sync entirely. Falls back to metadata-based
7
8
  * download for unknown models.
8
9
  */
9
- export declare function downloadModelFromRegistry(registryPath: string, registrySource: string, progressCallback?: (progress: ModelProgressUpdate) => void, expectedChecksum?: string): Promise<string>;
10
+ export declare function downloadModelFromRegistry(registryPath: string, registrySource: string, progressCallback?: (progress: ModelProgressUpdate) => void, expectedChecksum?: string, hooks?: DownloadMetricsHooks): Promise<string>;
10
11
  //# sourceMappingURL=registry.d.ts.map