@qvac/sdk 0.2.7-dev.1761566029.f834aa3 → 0.4.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 (215) hide show
  1. package/README.md +26 -3
  2. package/dist/client/api/cancel.d.ts +1 -1
  3. package/dist/client/api/cancel.js +4 -3
  4. package/dist/client/api/completion-stream.d.ts +24 -32
  5. package/dist/client/api/completion-stream.js +142 -50
  6. package/dist/client/api/delete-cache.js +3 -2
  7. package/dist/client/api/download-asset.d.ts +3 -3
  8. package/dist/client/api/download-asset.js +12 -17
  9. package/dist/client/api/embed.d.ts +1 -1
  10. package/dist/client/api/embed.js +4 -3
  11. package/dist/client/api/get-model-info.d.ts +29 -0
  12. package/dist/client/api/get-model-info.js +14 -0
  13. package/dist/client/api/index.d.ts +4 -0
  14. package/dist/client/api/index.js +4 -0
  15. package/dist/client/api/load-model.d.ts +3 -3
  16. package/dist/client/api/load-model.js +13 -22
  17. package/dist/client/api/logging-stream.d.ts +1 -1
  18. package/dist/client/api/logging-stream.js +3 -2
  19. package/dist/client/api/ping.d.ts +1 -1
  20. package/dist/client/api/ping.js +3 -2
  21. package/dist/client/api/provide.d.ts +1 -1
  22. package/dist/client/api/provide.js +4 -3
  23. package/dist/client/api/rag.d.ts +3 -3
  24. package/dist/client/api/rag.js +13 -12
  25. package/dist/client/api/set-config.d.ts +7 -0
  26. package/dist/client/api/set-config.js +20 -0
  27. package/dist/client/api/stop-provider.d.ts +15 -0
  28. package/dist/client/api/stop-provider.js +25 -0
  29. package/dist/client/api/text-to-speech.d.ts +7 -0
  30. package/dist/client/api/text-to-speech.js +58 -0
  31. package/dist/client/api/transcribe.d.ts +4 -2
  32. package/dist/client/api/transcribe.js +9 -5
  33. package/dist/client/api/translate.d.ts +1 -1
  34. package/dist/client/api/translate.js +3 -2
  35. package/dist/client/api/unload-model.d.ts +5 -1
  36. package/dist/client/api/unload-model.js +14 -4
  37. package/dist/client/config-manager.d.ts +4 -0
  38. package/dist/client/config-manager.js +8 -0
  39. package/dist/client/index.d.ts +1 -1
  40. package/dist/client/index.js +1 -1
  41. package/dist/client/init-hooks.d.ts +6 -0
  42. package/dist/client/init-hooks.js +37 -0
  43. package/dist/client/rpc/bare-client.d.ts +73 -0
  44. package/dist/client/rpc/bare-client.js +5 -4
  45. package/dist/client/rpc/bare-rpc-client.js +7 -3
  46. package/dist/client/rpc/expo-rpc-client.d.ts +1 -0
  47. package/dist/client/rpc/expo-rpc-client.js +9 -1
  48. package/dist/client/rpc/node-rpc-client.d.ts +1 -1
  49. package/dist/client/rpc/node-rpc-client.js +22 -9
  50. package/dist/client/rpc/rpc-client.d.ts +1 -0
  51. package/dist/client/rpc/rpc-client.js +27 -3
  52. package/dist/examples/cache-management.d.ts +2 -0
  53. package/dist/examples/cache-management.js +97 -0
  54. package/dist/examples/delegated-inference/consumer.js +2 -2
  55. package/dist/examples/download-with-blind-relays.d.ts +2 -0
  56. package/dist/examples/download-with-blind-relays.js +48 -0
  57. package/dist/examples/download-with-cancel.js +3 -4
  58. package/dist/examples/embed-hyperdrive.js +0 -1
  59. package/dist/examples/kv-cache-cleanup.js +0 -1
  60. package/dist/examples/kv-cache-custom-key.js +0 -1
  61. package/dist/examples/kv-cache-example.js +0 -1
  62. package/dist/examples/llamacpp-file-logging.js +0 -1
  63. package/dist/examples/llamacpp-filesystem.js +2 -2
  64. package/dist/examples/llamacpp-http.js +0 -1
  65. package/dist/examples/llamacpp-hyperdrive.js +0 -1
  66. package/dist/examples/llamacpp-multimodal.js +0 -1
  67. package/dist/examples/llamacpp-native-tools.js +118 -36
  68. package/dist/examples/llamacpp-sharded.d.ts +2 -0
  69. package/dist/examples/llamacpp-sharded.js +44 -0
  70. package/dist/examples/multi-model-demo.js +0 -1
  71. package/dist/examples/parallel-download.js +2 -2
  72. package/dist/examples/rag/rag-chromadb.js +0 -1
  73. package/dist/examples/rag/rag-hyperdb-workspaces.js +0 -1
  74. package/dist/examples/rag/rag-hyperdb.js +0 -1
  75. package/dist/examples/rag/rag-lancedb.js +0 -1
  76. package/dist/examples/rag/rag-sqlite.js +0 -1
  77. package/dist/examples/text-to-speech.d.ts +3 -0
  78. package/dist/examples/text-to-speech.js +137 -0
  79. package/dist/examples/translation/translation-indic.js +3 -1
  80. package/dist/examples/translation/translation-llm-context.js +0 -1
  81. package/dist/examples/translation/translation-llm.js +2 -2
  82. package/dist/examples/translation/translation-opus.js +3 -1
  83. package/dist/examples/translation/translation-stream.js +0 -1
  84. package/dist/examples/whispercpp-filesystem.js +32 -5
  85. package/dist/examples/whispercpp-microphone-record.js +9 -9
  86. package/dist/examples/whispercpp-prompt.d.ts +2 -0
  87. package/dist/examples/whispercpp-prompt.js +68 -0
  88. package/dist/expo/plugins/withMobileBundle.js +9 -3
  89. package/dist/index.d.ts +4 -2
  90. package/dist/index.js +4 -2
  91. package/dist/models/hyperdrive/models.d.ts +1924 -100
  92. package/dist/models/hyperdrive/models.js +2051 -105
  93. package/dist/schemas/common.d.ts +420 -58
  94. package/dist/schemas/common.js +12 -0
  95. package/dist/schemas/completion-stream.d.ts +26 -22
  96. package/dist/schemas/completion-stream.js +9 -23
  97. package/dist/schemas/download-asset.d.ts +77 -2
  98. package/dist/schemas/download-asset.js +15 -4
  99. package/dist/schemas/get-model-info.d.ts +100 -0
  100. package/dist/schemas/get-model-info.js +40 -0
  101. package/dist/schemas/index.d.ts +8 -0
  102. package/dist/schemas/index.js +8 -0
  103. package/dist/schemas/llamacpp-config.d.ts +2 -1
  104. package/dist/schemas/llamacpp-config.js +3 -4
  105. package/dist/schemas/load-model.d.ts +2316 -266
  106. package/dist/schemas/load-model.js +157 -10
  107. package/dist/schemas/model-src-utils.d.ts +98 -0
  108. package/dist/schemas/model-src-utils.js +31 -0
  109. package/dist/schemas/sdk-errors-client.d.ts +25 -0
  110. package/dist/schemas/sdk-errors-client.js +111 -0
  111. package/dist/schemas/sdk-errors-server.d.ts +55 -0
  112. package/dist/schemas/sdk-errors-server.js +271 -0
  113. package/dist/schemas/set-config.d.ts +21 -0
  114. package/dist/schemas/set-config.js +14 -0
  115. package/dist/schemas/stop-provide.d.ts +17 -0
  116. package/dist/schemas/stop-provide.js +15 -0
  117. package/dist/schemas/text-to-speech.d.ts +34 -0
  118. package/dist/schemas/text-to-speech.js +25 -0
  119. package/dist/schemas/tools.d.ts +62 -0
  120. package/dist/schemas/tools.js +43 -0
  121. package/dist/schemas/transcription.d.ts +25 -2
  122. package/dist/schemas/transcription.js +12 -1
  123. package/dist/schemas/translation-config.d.ts +33 -5
  124. package/dist/schemas/translation-config.js +18 -1
  125. package/dist/schemas/unload-model.d.ts +2 -0
  126. package/dist/schemas/unload-model.js +2 -0
  127. package/dist/schemas/whispercpp-config.d.ts +55 -18
  128. package/dist/schemas/whispercpp-config.js +63 -15
  129. package/dist/server/bare/addons/cancel.js +2 -1
  130. package/dist/server/bare/addons/llamacpp/create-model.d.ts +9 -2
  131. package/dist/server/bare/addons/llamacpp/create-model.js +23 -23
  132. package/dist/server/bare/addons/llamacpp/handlers/completion-stream.d.ts +10 -2
  133. package/dist/server/bare/addons/llamacpp/handlers/completion-stream.js +62 -43
  134. package/dist/server/bare/addons/llamacpp/handlers/embed.js +3 -2
  135. package/dist/server/bare/addons/llamacpp/kv-cache-utils.d.ts +1 -1
  136. package/dist/server/bare/addons/llamacpp/kv-cache-utils.js +6 -2
  137. package/dist/server/bare/addons/load-model.js +59 -28
  138. package/dist/server/bare/addons/translation/create-model.d.ts +5 -1
  139. package/dist/server/bare/addons/translation/create-model.js +17 -25
  140. package/dist/server/bare/addons/translation/handlers/translate.js +10 -1
  141. package/dist/server/bare/addons/tts/create-model.d.ts +10 -0
  142. package/dist/server/bare/addons/tts/create-model.js +25 -0
  143. package/dist/server/bare/addons/tts/handlers/text-to-speech.d.ts +3 -0
  144. package/dist/server/bare/addons/tts/handlers/text-to-speech.js +87 -0
  145. package/dist/server/bare/addons/tts/index.d.ts +3 -0
  146. package/dist/server/bare/addons/tts/index.js +2 -0
  147. package/dist/server/bare/addons/unload-model.js +21 -3
  148. package/dist/server/bare/addons/whispercpp/create-model.d.ts +5 -1
  149. package/dist/server/bare/addons/whispercpp/create-model.js +13 -32
  150. package/dist/server/bare/addons/whispercpp/handlers/transcribe-stream.js +41 -20
  151. package/dist/server/bare/delegate-rpc-client.js +3 -2
  152. package/dist/server/bare/hyperswarm.d.ts +3 -0
  153. package/dist/server/bare/hyperswarm.js +22 -1
  154. package/dist/server/bare/rag-hyperdb/rag-manager.js +16 -13
  155. package/dist/server/bare/registry/config-registry.d.ts +5 -0
  156. package/dist/server/bare/registry/config-registry.js +39 -0
  157. package/dist/server/bare/registry/logging-stream-registry.d.ts +1 -0
  158. package/dist/server/bare/registry/logging-stream-registry.js +7 -0
  159. package/dist/server/bare/registry/model-registry.d.ts +13 -0
  160. package/dist/server/bare/registry/model-registry.js +24 -7
  161. package/dist/server/rpc/handle-request.js +48 -3
  162. package/dist/server/rpc/handlers/completion-stream-delegated.js +2 -1
  163. package/dist/server/rpc/handlers/completion-stream.js +11 -4
  164. package/dist/server/rpc/handlers/download-asset.js +2 -3
  165. package/dist/server/rpc/handlers/get-model-info.d.ts +3 -0
  166. package/dist/server/rpc/handlers/get-model-info.js +148 -0
  167. package/dist/server/rpc/handlers/index.d.ts +6 -0
  168. package/dist/server/rpc/handlers/index.js +8 -0
  169. package/dist/server/rpc/handlers/load-model/download-manager.d.ts +1 -0
  170. package/dist/server/rpc/handlers/load-model/download-manager.js +12 -31
  171. package/dist/server/rpc/handlers/load-model/http.js +51 -10
  172. package/dist/server/rpc/handlers/load-model/hyperdrive.js +336 -156
  173. package/dist/server/rpc/handlers/load-model/index.js +1 -1
  174. package/dist/server/rpc/handlers/load-model/resolve.d.ts +1 -1
  175. package/dist/server/rpc/handlers/load-model/resolve.js +17 -60
  176. package/dist/server/rpc/handlers/load-model-delegated.js +7 -4
  177. package/dist/server/rpc/handlers/load-model.js +19 -1
  178. package/dist/server/rpc/handlers/provideHandler/handler.js +2 -1
  179. package/dist/server/rpc/handlers/rag.js +0 -3
  180. package/dist/server/rpc/handlers/set-config.d.ts +3 -0
  181. package/dist/server/rpc/handlers/set-config.js +18 -0
  182. package/dist/server/rpc/handlers/stopProvideHandler.d.ts +3 -0
  183. package/dist/server/rpc/handlers/stopProvideHandler.js +22 -0
  184. package/dist/server/rpc/handlers/text-to-speech.d.ts +3 -0
  185. package/dist/server/rpc/handlers/text-to-speech.js +7 -0
  186. package/dist/server/rpc/handlers/transcribe-stream.js +6 -2
  187. package/dist/server/rpc/handlers/unload-model.js +7 -0
  188. package/dist/server/utils/cache.d.ts +13 -8
  189. package/dist/server/utils/cache.js +69 -14
  190. package/dist/server/utils/checksum.d.ts +2 -0
  191. package/dist/server/utils/checksum.js +24 -0
  192. package/dist/server/utils/index.d.ts +2 -0
  193. package/dist/server/utils/index.js +2 -0
  194. package/dist/server/utils/shard-utils.d.ts +22 -0
  195. package/dist/server/utils/shard-utils.js +37 -0
  196. package/dist/server/utils/tool-integration.d.ts +13 -0
  197. package/dist/server/utils/tool-integration.js +43 -0
  198. package/dist/server/utils/tool-parser.d.ts +7 -0
  199. package/dist/server/utils/tool-parser.js +244 -0
  200. package/dist/server/worker.js +28 -10
  201. package/dist/utils/errors-base.d.ts +3 -0
  202. package/dist/utils/errors-base.js +13 -0
  203. package/dist/utils/errors-client.d.ts +107 -0
  204. package/dist/utils/errors-client.js +186 -0
  205. package/dist/utils/errors-server.d.ts +146 -0
  206. package/dist/utils/errors-server.js +253 -0
  207. package/dist/utils/tool-helpers.d.ts +17 -0
  208. package/dist/utils/tool-helpers.js +99 -0
  209. package/package.json +15 -11
  210. package/dist/examples/llamacpp-tools-routing.d.ts +0 -2
  211. package/dist/examples/llamacpp-tools-routing.js +0 -364
  212. package/dist/examples/llamacpp-tools.d.ts +0 -2
  213. package/dist/examples/llamacpp-tools.js +0 -81
  214. package/dist/server/http-server.d.ts +0 -2
  215. package/dist/server/http-server.js +0 -189
@@ -1,8 +1,8 @@
1
1
  import { RAG, HyperDBAdapter } from "@qvac/rag";
2
2
  import Corestore from "corestore";
3
3
  import path from "bare-path";
4
- import process from "bare-process";
5
4
  import { getEnv } from "../../worker.js";
5
+ import { RAGWorkspaceModelMismatchError } from "../../../utils/errors-server.js";
6
6
  const ragInstances = new Map();
7
7
  const defaultWorkspace = "default";
8
8
  const getStorePath = (workspace) => {
@@ -15,9 +15,7 @@ export const getRagInstance = async (modelId, embeddingFunction, workspace) => {
15
15
  if (existingEntry) {
16
16
  // Validate model consistency
17
17
  if (existingEntry.modelId !== modelId) {
18
- throw new Error(`Workspace "${key}" is configured for model "${existingEntry.modelId}", ` +
19
- `but you're trying to use model "${modelId}". ` +
20
- `Use a different workspace or the same model.`);
18
+ throw new RAGWorkspaceModelMismatchError(key, existingEntry.modelId, modelId);
21
19
  }
22
20
  return existingEntry.rag;
23
21
  }
@@ -48,14 +46,19 @@ export const closeRagInstance = async (workspace) => {
48
46
  ragInstances.delete(key);
49
47
  }
50
48
  };
49
+ let isCleaningUp = false;
51
50
  export const closeAllRagInstances = async () => {
52
- const closures = Array.from(ragInstances.entries()).map(async ([key, entry]) => {
53
- await entry.rag.close();
54
- ragInstances.delete(key);
55
- });
56
- await Promise.all(closures);
51
+ if (isCleaningUp)
52
+ return;
53
+ isCleaningUp = true;
54
+ try {
55
+ const closures = Array.from(ragInstances.entries()).map(async ([key, entry]) => {
56
+ await entry.rag.close();
57
+ ragInstances.delete(key);
58
+ });
59
+ await Promise.all(closures);
60
+ }
61
+ catch (error) {
62
+ console.error("❌ Error during RAG cleanup:", error);
63
+ }
57
64
  };
58
- // Ensure cleanup on process exit
59
- process.on("SIGINT", () => {
60
- void closeAllRagInstances();
61
- });
@@ -0,0 +1,5 @@
1
+ import type { SDKConfig } from "../../../schemas/index";
2
+ export declare const setSDKConfig: (config: SDKConfig) => void;
3
+ export declare const getSDKConfig: () => SDKConfig;
4
+ export declare const getConfiguredCacheDir: () => string;
5
+ //# sourceMappingURL=config-registry.d.ts.map
@@ -0,0 +1,39 @@
1
+ import fs from "bare-fs";
2
+ import path from "bare-path";
3
+ import { getEnv } from "../../worker.js";
4
+ import { CacheDirNotAbsoluteError, CacheDirNotWritableError, } from "../../../utils/errors-server.js";
5
+ const configRegistry = {
6
+ cacheDirectory: undefined,
7
+ swarmRelays: undefined,
8
+ };
9
+ export const setSDKConfig = (config) => {
10
+ if (config.cacheDirectory !== undefined && config.cacheDirectory !== null) {
11
+ if (!path.isAbsolute(config.cacheDirectory)) {
12
+ throw new CacheDirNotAbsoluteError();
13
+ }
14
+ try {
15
+ fs.mkdirSync(config.cacheDirectory, { recursive: true });
16
+ const testFile = path.join(config.cacheDirectory, ".qvac-test");
17
+ fs.writeFileSync(testFile, "test");
18
+ fs.unlinkSync(testFile);
19
+ }
20
+ catch (error) {
21
+ throw new CacheDirNotWritableError(config.cacheDirectory, error instanceof Error ? error.message : String(error), error);
22
+ }
23
+ configRegistry.cacheDirectory = config.cacheDirectory;
24
+ console.log(`✅ Cache directory set to: ${config.cacheDirectory}`);
25
+ }
26
+ if (config.swarmRelays !== undefined && config.swarmRelays !== null) {
27
+ configRegistry.swarmRelays = config.swarmRelays;
28
+ }
29
+ };
30
+ export const getSDKConfig = () => {
31
+ return { ...configRegistry };
32
+ };
33
+ const getDefaultCacheDir = () => {
34
+ const homeDir = getEnv().HOME_DIR;
35
+ return path.join(homeDir, ".qvac", "models");
36
+ };
37
+ export const getConfiguredCacheDir = () => {
38
+ return configRegistry.cacheDirectory || getDefaultCacheDir();
39
+ };
@@ -9,4 +9,5 @@ export declare function getLoggingStreamStats(): {
9
9
  modelIds: string[];
10
10
  totalStreams: number;
11
11
  };
12
+ export declare function clearAllLoggingStreams(): void;
12
13
  //# sourceMappingURL=logging-stream-registry.d.ts.map
@@ -44,3 +44,10 @@ export function getLoggingStreamStats() {
44
44
  totalStreams: Array.from(loggingStreams.values()).reduce((sum, streams) => sum + streams.size, 0),
45
45
  };
46
46
  }
47
+ export function clearAllLoggingStreams() {
48
+ const count = loggingStreams.size;
49
+ loggingStreams.clear();
50
+ if (count > 0) {
51
+ console.log(`🧹 Cleared logging streams for ${count} model(s)`);
52
+ }
53
+ }
@@ -1,4 +1,5 @@
1
1
  import type EventEmitter from "events";
2
+ import type FilesystemDL from "@qvac/dl-filesystem";
2
3
  interface AddonInterface {
3
4
  cancel(jobId?: string): Promise<void>;
4
5
  }
@@ -8,6 +9,11 @@ export interface AnyModel {
8
9
  onUpdate(callback: (data: string) => void): {
9
10
  await: () => Promise<void>;
10
11
  };
12
+ onUpdate(callback: (data: {
13
+ outputArray: Int16Array;
14
+ }) => void): {
15
+ await: () => Promise<void>;
16
+ };
11
17
  onError(callback: (error: Error) => void): void;
12
18
  onUpdate(callback: (data: Array<{
13
19
  text: string;
@@ -20,6 +26,7 @@ export interface AnyModel {
20
26
  }>>;
21
27
  await(): Promise<void>;
22
28
  }>;
29
+ reload?(config: unknown): Promise<void>;
23
30
  unload?(): Promise<void>;
24
31
  addon?: AddonInterface;
25
32
  }
@@ -33,6 +40,8 @@ interface LocalOptions {
33
40
  path: string;
34
41
  loadedAt: Date;
35
42
  config: unknown;
43
+ name?: string | undefined;
44
+ loader: FilesystemDL;
36
45
  }
37
46
  export interface ModelEntry {
38
47
  id: string;
@@ -44,6 +53,8 @@ export declare function registerModel(id: string, options: {
44
53
  model: AnyModel;
45
54
  path: string;
46
55
  config: unknown;
56
+ loader: FilesystemDL;
57
+ name?: string | undefined;
47
58
  } | {
48
59
  topic: string;
49
60
  providerPublicKey: string;
@@ -59,8 +70,10 @@ export declare function getModelInfo(id: string): {
59
70
  path: string;
60
71
  loadedAt: Date;
61
72
  config: unknown;
73
+ name?: string;
62
74
  } | null;
63
75
  export declare function getModelConfig(id: string): unknown;
76
+ export declare function updateModelConfig(id: string, config: unknown): void;
64
77
  export declare function clearRegistry(): void;
65
78
  export declare function getRegistryStats(): {
66
79
  totalModels: number;
@@ -1,8 +1,9 @@
1
+ import { ModelAlreadyRegisteredError, ModelNotFoundError, ModelIsDelegatedError, } from "../../../utils/errors-server.js";
1
2
  // Global registry state - using stateless functions to manage it
2
3
  const modelRegistry = new Map();
3
4
  export function registerModel(id, options) {
4
5
  if (modelRegistry.has(id)) {
5
- throw new Error(`Model with ID "${id}" is already registered`);
6
+ throw new ModelAlreadyRegisteredError(id);
6
7
  }
7
8
  const isDelegated = "topic" in options && "providerPublicKey" in options;
8
9
  if (isDelegated) {
@@ -27,9 +28,12 @@ export function registerModel(id, options) {
27
28
  path: options.path,
28
29
  loadedAt: new Date(),
29
30
  config: options.config,
31
+ loader: options.loader,
32
+ name: options.name,
30
33
  },
31
34
  });
32
- console.log(`Local model registered: ${id} -> ${options.path}`);
35
+ const nameStr = options.name ? ` (${options.name})` : "";
36
+ console.log(`Local model registered: ${id}${nameStr} -> ${options.path}`);
33
37
  }
34
38
  }
35
39
  export function getModelEntry(id) {
@@ -38,11 +42,10 @@ export function getModelEntry(id) {
38
42
  export function getModel(id) {
39
43
  const entry = modelRegistry.get(id);
40
44
  if (!entry) {
41
- const availableIds = Array.from(modelRegistry.keys());
42
- throw new Error(`Model with ID "${id}" not found in registry. Available models: ${availableIds.join(", ")}`);
45
+ throw new ModelNotFoundError(id);
43
46
  }
44
47
  if (!entry.local) {
45
- throw new Error(`Model with ID "${id}" is delegated and cannot be accessed as a local model`);
48
+ throw new ModelIsDelegatedError(id);
46
49
  }
47
50
  return entry.local.model;
48
51
  }
@@ -66,20 +69,34 @@ export function getModelInfo(id) {
66
69
  if (!entry || !entry.local) {
67
70
  return null;
68
71
  }
69
- return {
72
+ const result = {
70
73
  id: entry.id,
71
74
  path: entry.local.path,
72
75
  loadedAt: entry.local.loadedAt,
73
76
  config: entry.local.config,
74
77
  };
78
+ if (entry.local.name) {
79
+ result.name = entry.local.name;
80
+ }
81
+ return result;
75
82
  }
76
83
  export function getModelConfig(id) {
77
84
  const entry = modelRegistry.get(id);
78
85
  if (!entry || !entry.local) {
79
- throw new Error(`Model with ID "${id}" not found or is delegated`);
86
+ throw new ModelNotFoundError(id);
80
87
  }
81
88
  return entry.local.config;
82
89
  }
90
+ export function updateModelConfig(id, config) {
91
+ const entry = modelRegistry.get(id);
92
+ if (!entry) {
93
+ throw new ModelNotFoundError(id);
94
+ }
95
+ if (!entry.local) {
96
+ throw new ModelIsDelegatedError(id);
97
+ }
98
+ entry.local.config = config;
99
+ }
83
100
  export function clearRegistry() {
84
101
  modelRegistry.clear();
85
102
  console.log("Model registry cleared");
@@ -12,14 +12,19 @@ import { handleTranslate } from "./handlers/translate.js";
12
12
  import { handleLoggingStream } from "./handlers/logging-stream.js";
13
13
  import { cancelHandler } from "./handlers/cancelHandler.js";
14
14
  import { provideHandler } from "./handlers/provideHandler.js";
15
+ import { stopProvideHandler } from "./handlers/stopProvideHandler.js";
15
16
  import { handleRag } from "./handlers/rag.js";
16
17
  import { handleDeleteCache } from "./handlers/delete-cache.js";
17
- import { sendErrorResponse, sendStreamErrorResponse } from "../error-handlers";
18
+ import { handleTextToSpeech } from "./handlers/text-to-speech.js";
19
+ import { handleSetConfig } from "./handlers/set-config.js";
20
+ import { handleGetModelInfo } from "./handlers/get-model-info.js";
21
+ import { sendErrorResponse, sendStreamErrorResponse, } from "../error-handlers.js";
22
+ import { NoDataReceivedError, UnknownRequestTypeError, } from "../../utils/errors-client.js";
18
23
  export async function handleRequest(req) {
19
24
  try {
20
25
  const rawData = req.data?.toString();
21
26
  if (!rawData) {
22
- throw new Error("No data received");
27
+ throw new NoDataReceivedError();
23
28
  }
24
29
  const jsonData = JSON.parse(rawData);
25
30
  const request = requestSchema.parse(jsonData);
@@ -200,6 +205,11 @@ export async function handleRequest(req) {
200
205
  req.reply(JSON.stringify(responseSchema.parse(response)), "utf-8");
201
206
  break;
202
207
  }
208
+ case "stopProvide": {
209
+ const response = stopProvideHandler(request);
210
+ req.reply(JSON.stringify(responseSchema.parse(response)), "utf-8");
211
+ break;
212
+ }
203
213
  case "rag": {
204
214
  try {
205
215
  const response = await handleRag(request);
@@ -220,8 +230,43 @@ export async function handleRequest(req) {
220
230
  }
221
231
  break;
222
232
  }
233
+ case "textToSpeech": {
234
+ const stream = req.createResponseStream();
235
+ try {
236
+ for await (const response of handleTextToSpeech(request)) {
237
+ const validatedResponse = responseSchema.parse(response);
238
+ const data = JSON.stringify(validatedResponse);
239
+ stream.write(data + "\n", "utf-8");
240
+ }
241
+ stream.end();
242
+ }
243
+ catch (error) {
244
+ sendStreamErrorResponse(stream, error);
245
+ }
246
+ break;
247
+ }
248
+ case "setConfig": {
249
+ try {
250
+ const response = handleSetConfig(request);
251
+ req.reply(JSON.stringify(responseSchema.parse(response)), "utf-8");
252
+ }
253
+ catch (error) {
254
+ sendErrorResponse(req, error);
255
+ }
256
+ break;
257
+ }
258
+ case "getModelInfo": {
259
+ try {
260
+ const response = await handleGetModelInfo(request);
261
+ req.reply(JSON.stringify(responseSchema.parse(response)), "utf-8");
262
+ }
263
+ catch (error) {
264
+ sendErrorResponse(req, error);
265
+ }
266
+ break;
267
+ }
223
268
  default: {
224
- throw new Error(`Unknown request type`);
269
+ throw new UnknownRequestTypeError();
225
270
  }
226
271
  }
227
272
  }
@@ -1,11 +1,12 @@
1
1
  import { getModelEntry } from "../../bare/registry/model-registry.js";
2
2
  import { getRPC } from "../../bare/delegate-rpc-client.js";
3
3
  import { stream } from "../../../client/rpc/rpc-client.js";
4
+ import { ModelIsDelegatedError } from "../../../utils/errors-server.js";
4
5
  export async function* handleCompletionStreamDelegated(request) {
5
6
  // Get delegation info from model registry
6
7
  const entry = getModelEntry(request.modelId);
7
8
  if (!entry?.isDelegated || !entry.delegated) {
8
- throw new Error(`Model ${request.modelId} is not a delegated model`);
9
+ throw new ModelIsDelegatedError(request.modelId);
9
10
  }
10
11
  const { topic, providerPublicKey, timeout } = entry.delegated;
11
12
  try {
@@ -9,30 +9,37 @@ export async function* handleCompletionStream(request) {
9
9
  history: filteredHistory,
10
10
  modelId: request.modelId,
11
11
  kvCache: request.kvCache,
12
+ ...(request.tools && { tools: request.tools }),
12
13
  });
13
14
  let stats;
15
+ let toolCalls = [];
14
16
  let done = false;
15
17
  let buffer = "";
16
18
  while (!done) {
17
19
  const result = await stream.next();
18
20
  if (result.done) {
19
- stats = result.value;
21
+ stats = result.value.stats;
22
+ toolCalls = result.value.toolCalls;
20
23
  done = true;
21
24
  }
22
25
  else {
23
- buffer += result.value;
24
26
  if (request.stream) {
25
27
  yield {
26
28
  type: "completionStream",
27
- token: result.value,
29
+ token: result.value.token,
30
+ toolCallEvent: result.value.toolCallEvent,
28
31
  };
29
32
  }
33
+ else {
34
+ buffer += result.value.token;
35
+ }
30
36
  }
31
37
  }
32
38
  yield {
33
39
  type: "completionStream",
34
- token: buffer,
40
+ token: request.stream ? "" : buffer,
35
41
  done: true,
36
42
  stats,
43
+ toolCalls,
37
44
  };
38
45
  }
@@ -1,13 +1,12 @@
1
1
  import { resolveModelPath } from "./load-model/resolve.js";
2
- import path from "bare-path";
3
2
  export async function handleDownloadAsset(request, progressCallback) {
4
3
  const { assetSrc, seed } = request;
5
4
  try {
6
- const assetPath = await resolveModelPath(assetSrc, progressCallback, seed);
5
+ await resolveModelPath(assetSrc, progressCallback, seed);
7
6
  return {
8
7
  type: "downloadAsset",
9
8
  success: true,
10
- assetId: path.basename(assetPath),
9
+ assetId: assetSrc,
11
10
  };
12
11
  }
13
12
  catch (error) {
@@ -0,0 +1,3 @@
1
+ import type { GetModelInfoRequest, GetModelInfoResponse } from "../../../schemas/index";
2
+ export declare const handleGetModelInfo: (request: GetModelInfoRequest) => Promise<GetModelInfoResponse>;
3
+ //# sourceMappingURL=get-model-info.d.ts.map
@@ -0,0 +1,148 @@
1
+ import { models } from "../../../models/hyperdrive/models.js";
2
+ import { getAllModelIds, getModelEntry, } from "../../bare/registry/model-registry.js";
3
+ import { getConfiguredCacheDir } from "../../bare/registry/config-registry.js";
4
+ import { generateShortHash } from "../../utils/index.js";
5
+ import { promises as fsPromises } from "bare-fs";
6
+ import path from "bare-path";
7
+ import { getShardPath } from "../../utils/cache.js";
8
+ import { ModelNotFoundError } from "../../../utils/errors-server.js";
9
+ export const handleGetModelInfo = async (request) => {
10
+ const { name } = request;
11
+ const catalogEntry = models.find((m) => m.name === name);
12
+ if (!catalogEntry) {
13
+ throw new ModelNotFoundError(`${name}" not found in catalog. Use model names from the catalog (e.g., "WHISPER_TINY", "EMBEDDINGGEMMA_300M_Q4_0")`);
14
+ }
15
+ const cacheStatus = catalogEntry.shardMetadata && catalogEntry.shardMetadata.length > 0
16
+ ? await handleShardedModel(catalogEntry.hyperdriveKey, catalogEntry.shardMetadata)
17
+ : await handleSingleFileModel(catalogEntry.hyperdriveKey, catalogEntry.modelId, catalogEntry.expectedSize, catalogEntry.sha256Checksum);
18
+ const { cacheFiles, isCached, actualSize, cachedAt } = cacheStatus;
19
+ const loadedModelIds = getAllModelIds();
20
+ const loadedInstances = [];
21
+ for (const id of loadedModelIds) {
22
+ const entry = getModelEntry(id);
23
+ if (!entry?.local)
24
+ continue;
25
+ const matchesByName = entry.local.name && entry.local.name === name;
26
+ const matchesByPath = cacheFiles.length > 0 && entry.local.path === cacheFiles[0]?.path;
27
+ if (matchesByName || matchesByPath) {
28
+ const instance = {
29
+ registryId: id,
30
+ loadedAt: entry.local.loadedAt,
31
+ config: entry.local.config,
32
+ };
33
+ loadedInstances.push(instance);
34
+ }
35
+ }
36
+ const isLoaded = loadedInstances.length > 0;
37
+ const modelInfo = {
38
+ name: catalogEntry.name,
39
+ modelId: catalogEntry.modelId,
40
+ hyperdriveKey: catalogEntry.hyperdriveKey,
41
+ hyperbeeKey: catalogEntry.hyperbeeKey,
42
+ expectedSize: catalogEntry.expectedSize,
43
+ sha256Checksum: catalogEntry.sha256Checksum,
44
+ addon: catalogEntry.addon,
45
+ isCached,
46
+ isLoaded,
47
+ cacheFiles,
48
+ actualSize,
49
+ cachedAt,
50
+ loadedInstances: loadedInstances.length > 0 ? loadedInstances : undefined,
51
+ };
52
+ return {
53
+ type: "getModelInfo",
54
+ modelInfo,
55
+ };
56
+ };
57
+ async function handleShardedModel(hyperdriveKey, shardMetadata) {
58
+ const cacheFiles = [];
59
+ let allShardsCached = true;
60
+ let totalActualSize = 0;
61
+ let latestCachedAt;
62
+ for (const shard of shardMetadata) {
63
+ const shardPath = getShardPath(hyperdriveKey, shard.filename);
64
+ let shardIsCached = false;
65
+ let shardActualSize;
66
+ let shardCachedAt;
67
+ try {
68
+ const stats = await fsPromises.stat(shardPath);
69
+ shardIsCached = stats.isFile();
70
+ if (shardIsCached) {
71
+ shardActualSize = stats.size;
72
+ shardCachedAt = stats.mtime;
73
+ totalActualSize += stats.size;
74
+ if (!latestCachedAt || stats.mtime > latestCachedAt) {
75
+ latestCachedAt = stats.mtime;
76
+ }
77
+ }
78
+ else {
79
+ allShardsCached = false;
80
+ }
81
+ }
82
+ catch {
83
+ shardIsCached = false;
84
+ allShardsCached = false;
85
+ }
86
+ cacheFiles.push({
87
+ filename: shard.filename,
88
+ path: shardPath,
89
+ expectedSize: shard.expectedSize,
90
+ sha256Checksum: shard.sha256Checksum,
91
+ isCached: shardIsCached,
92
+ actualSize: shardActualSize,
93
+ cachedAt: shardCachedAt,
94
+ });
95
+ }
96
+ const result = {
97
+ cacheFiles,
98
+ isCached: allShardsCached,
99
+ };
100
+ if (allShardsCached) {
101
+ result.actualSize = totalActualSize;
102
+ if (latestCachedAt) {
103
+ result.cachedAt = latestCachedAt;
104
+ }
105
+ }
106
+ return result;
107
+ }
108
+ async function handleSingleFileModel(hyperdriveKey, modelId, expectedSize, sha256Checksum) {
109
+ const cacheDir = getConfiguredCacheDir();
110
+ const sourceHash = generateShortHash(`${hyperdriveKey}/${modelId}`);
111
+ const filePath = path.join(cacheDir, `${sourceHash}_${modelId}`);
112
+ let fileIsCached = false;
113
+ let fileActualSize;
114
+ let fileCachedAt;
115
+ try {
116
+ const stats = await fsPromises.stat(filePath);
117
+ fileIsCached = stats.isFile();
118
+ if (fileIsCached) {
119
+ fileActualSize = stats.size;
120
+ fileCachedAt = stats.mtime;
121
+ }
122
+ }
123
+ catch {
124
+ fileIsCached = false;
125
+ }
126
+ const cacheFiles = [
127
+ {
128
+ filename: modelId,
129
+ path: filePath,
130
+ expectedSize,
131
+ sha256Checksum,
132
+ isCached: fileIsCached,
133
+ actualSize: fileActualSize,
134
+ cachedAt: fileCachedAt,
135
+ },
136
+ ];
137
+ const result = {
138
+ cacheFiles,
139
+ isCached: fileIsCached,
140
+ };
141
+ if (fileActualSize !== undefined) {
142
+ result.actualSize = fileActualSize;
143
+ }
144
+ if (fileCachedAt !== undefined) {
145
+ result.cachedAt = fileCachedAt;
146
+ }
147
+ return result;
148
+ }
@@ -5,11 +5,13 @@ import { handleUnloadModel } from "./unload-model";
5
5
  import { handleEmbed } from "./embed";
6
6
  import { handleTranscribeStream } from "./transcribe-stream";
7
7
  import { provideHandler } from "./provideHandler";
8
+ import { stopProvideHandler } from "./stopProvideHandler";
8
9
  import { handleTranslate } from "./translate";
9
10
  import { handleLoggingStream } from "./logging-stream";
10
11
  import { handleRag } from "./rag";
11
12
  import { cancelHandler } from "./cancelHandler";
12
13
  import { handleDeleteCache } from "./delete-cache";
14
+ import { handleTextToSpeech } from "./text-to-speech";
13
15
  export declare const handlers: {
14
16
  completionStream: typeof handleCompletionStream;
15
17
  downloadAsset: typeof handleDownloadAsset;
@@ -19,9 +21,13 @@ export declare const handlers: {
19
21
  embed: typeof handleEmbed;
20
22
  transcribeStream: typeof handleTranscribeStream;
21
23
  provide: typeof provideHandler;
24
+ stopProvide: typeof stopProvideHandler;
22
25
  translate: typeof handleTranslate;
23
26
  loggingStream: typeof handleLoggingStream;
24
27
  rag: typeof handleRag;
25
28
  cancel: typeof cancelHandler;
29
+ textToSpeech: typeof handleTextToSpeech;
30
+ setConfig: (request: import("../../../schemas").SetConfigRequest) => import("../../../schemas").SetConfigResponse;
31
+ getModelInfo: (request: import("../../../schemas").GetModelInfoRequest) => Promise<import("../../../schemas").GetModelInfoResponse>;
26
32
  };
27
33
  //# sourceMappingURL=index.d.ts.map
@@ -5,11 +5,15 @@ import { handleUnloadModel } from "./unload-model.js";
5
5
  import { handleEmbed } from "./embed.js";
6
6
  import { handleTranscribeStream } from "./transcribe-stream.js";
7
7
  import { provideHandler } from "./provideHandler.js";
8
+ import { stopProvideHandler } from "./stopProvideHandler.js";
8
9
  import { handleTranslate } from "./translate.js";
9
10
  import { handleLoggingStream } from "./logging-stream.js";
10
11
  import { handleRag } from "./rag.js";
11
12
  import { cancelHandler } from "./cancelHandler.js";
12
13
  import { handleDeleteCache } from "./delete-cache.js";
14
+ import { handleTextToSpeech } from "./text-to-speech.js";
15
+ import { handleSetConfig } from "./set-config.js";
16
+ import { handleGetModelInfo } from "./get-model-info.js";
13
17
  export const handlers = {
14
18
  completionStream: handleCompletionStream,
15
19
  downloadAsset: handleDownloadAsset,
@@ -19,8 +23,12 @@ export const handlers = {
19
23
  embed: handleEmbed,
20
24
  transcribeStream: handleTranscribeStream,
21
25
  provide: provideHandler,
26
+ stopProvide: stopProvideHandler,
22
27
  translate: handleTranslate,
23
28
  loggingStream: handleLoggingStream,
24
29
  rag: handleRag,
25
30
  cancel: cancelHandler,
31
+ textToSpeech: handleTextToSpeech,
32
+ setConfig: handleSetConfig,
33
+ getModelInfo: handleGetModelInfo,
26
34
  };
@@ -9,4 +9,5 @@ export declare const shouldClearCache: (downloadKey: string) => boolean;
9
9
  export declare const clearClearCacheFlag: (downloadKey: string) => void;
10
10
  export declare const createCancelFunction: (downloadKey: string, clearCache?: boolean) => () => void;
11
11
  export declare const cancelAllDownloads: () => void;
12
+ export declare const cleanupDownloads: () => Promise<void>;
12
13
  //# sourceMappingURL=download-manager.d.ts.map