@qvac/sdk 0.4.0 → 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 (181) 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/constants/audio.d.ts +1 -2
  36. package/dist/constants/audio.js +1 -17
  37. package/dist/examples/config/config-path.d.ts +8 -0
  38. package/dist/examples/config/config-path.js +13 -0
  39. package/dist/examples/config-reload.d.ts +2 -0
  40. package/dist/examples/config-reload.js +49 -0
  41. package/dist/examples/download-with-blind-relays.js +20 -20
  42. package/dist/examples/embed-hyperdrive.js +35 -3
  43. package/dist/examples/kv-cache-cleanup.js +1 -1
  44. package/dist/examples/kv-cache-custom-key.js +1 -1
  45. package/dist/examples/kv-cache-example.js +1 -1
  46. package/dist/examples/llamacpp-hyperdrive.js +1 -1
  47. package/dist/examples/llamacpp-sharded.js +1 -1
  48. package/dist/examples/logging-file-transport.d.ts +2 -0
  49. package/dist/examples/{llamacpp-file-logging.js → logging-file-transport.js} +3 -7
  50. package/dist/examples/logging-streaming.d.ts +2 -0
  51. package/dist/examples/logging-streaming.js +75 -0
  52. package/dist/examples/mcp-websearch.d.ts +13 -0
  53. package/dist/examples/mcp-websearch.js +176 -0
  54. package/dist/index.d.ts +4 -4
  55. package/dist/index.js +2 -2
  56. package/dist/logging/addon.d.ts +6 -0
  57. package/dist/logging/addon.js +59 -0
  58. package/dist/logging/base-logger.js +24 -14
  59. package/dist/logging/client-logger.d.ts +3 -0
  60. package/dist/logging/client-logger.js +13 -0
  61. package/dist/logging/index.d.ts +6 -1
  62. package/dist/logging/index.js +6 -1
  63. package/dist/logging/logger.d.ts +0 -2
  64. package/dist/logging/logger.js +0 -3
  65. package/dist/logging/namespaces.d.ts +11 -0
  66. package/dist/logging/namespaces.js +11 -0
  67. package/dist/logging/registry.d.ts +26 -0
  68. package/dist/logging/registry.js +36 -0
  69. package/dist/logging/server-logger.d.ts +3 -0
  70. package/dist/logging/server-logger.js +16 -0
  71. package/dist/logging/stream-logger.d.ts +1 -1
  72. package/dist/logging/stream-logger.js +6 -3
  73. package/dist/logging/types.d.ts +2 -0
  74. package/dist/models/hyperdrive/models.d.ts +789 -51
  75. package/dist/models/hyperdrive/models.js +979 -200
  76. package/dist/schemas/common.d.ts +86 -23
  77. package/dist/schemas/common.js +0 -3
  78. package/dist/schemas/download-asset.d.ts +5 -5
  79. package/dist/schemas/embed.d.ts +3 -3
  80. package/dist/schemas/embed.js +9 -2
  81. package/dist/schemas/get-model-info.d.ts +2 -2
  82. package/dist/schemas/index.d.ts +5 -1
  83. package/dist/schemas/index.js +5 -1
  84. package/dist/schemas/json-schema.d.ts +16 -0
  85. package/dist/schemas/json-schema.js +2 -0
  86. package/dist/schemas/llamacpp-config.d.ts +5 -4
  87. package/dist/schemas/llamacpp-config.js +7 -5
  88. package/dist/schemas/load-model.d.ts +931 -211
  89. package/dist/schemas/load-model.js +7 -1
  90. package/dist/schemas/logging-stream.d.ts +10 -3
  91. package/dist/schemas/logging-stream.js +4 -3
  92. package/dist/schemas/mcp-adapter.d.ts +47 -0
  93. package/dist/schemas/mcp-adapter.js +1 -0
  94. package/dist/schemas/model-src-utils.d.ts +8 -6
  95. package/dist/schemas/model-src-utils.js +8 -3
  96. package/dist/schemas/reload-config.d.ts +344 -0
  97. package/dist/schemas/reload-config.js +42 -0
  98. package/dist/schemas/sdk-config.d.ts +22 -0
  99. package/dist/schemas/sdk-config.js +33 -0
  100. package/dist/schemas/sdk-errors-client.d.ts +4 -0
  101. package/dist/schemas/sdk-errors-client.js +20 -0
  102. package/dist/schemas/sdk-errors-server.d.ts +3 -0
  103. package/dist/schemas/sdk-errors-server.js +15 -0
  104. package/dist/schemas/tools.d.ts +3 -0
  105. package/dist/schemas/translation-config.d.ts +81 -0
  106. package/dist/schemas/translation-config.js +3 -4
  107. package/dist/schemas/whispercpp-config.d.ts +9 -1
  108. package/dist/schemas/whispercpp-config.js +2 -1
  109. package/dist/server/bare/addons/llamacpp/create-model.js +13 -4
  110. package/dist/server/bare/addons/llamacpp/handlers/embed.d.ts +9 -1
  111. package/dist/server/bare/addons/llamacpp/handlers/embed.js +18 -4
  112. package/dist/server/bare/addons/llamacpp/kv-cache-utils.js +6 -4
  113. package/dist/server/bare/addons/load-model.js +10 -4
  114. package/dist/server/bare/addons/unload-model.js +6 -3
  115. package/dist/server/bare/addons/whispercpp/handlers/transcribe-stream.js +56 -37
  116. package/dist/server/bare/delegate-rpc-client.js +12 -10
  117. package/dist/server/bare/hyperswarm.js +7 -5
  118. package/dist/server/bare/rag-hyperdb/rag-manager.js +3 -1
  119. package/dist/server/bare/registry/config-registry.d.ts +13 -4
  120. package/dist/server/bare/registry/config-registry.js +42 -10
  121. package/dist/server/bare/registry/logging-stream-registry.d.ts +24 -7
  122. package/dist/server/bare/registry/logging-stream-registry.js +99 -20
  123. package/dist/server/bare/registry/model-registry.d.ts +3 -0
  124. package/dist/server/bare/registry/model-registry.js +9 -6
  125. package/dist/server/rpc/create-server.js +5 -3
  126. package/dist/server/rpc/handle-request.js +30 -16
  127. package/dist/server/rpc/handlers/cancelHandler.js +3 -1
  128. package/dist/server/rpc/handlers/completion-stream-delegated.js +4 -2
  129. package/dist/server/rpc/handlers/delete-cache.js +3 -1
  130. package/dist/server/rpc/handlers/download-asset.js +3 -1
  131. package/dist/server/rpc/handlers/embed.js +3 -1
  132. package/dist/server/rpc/handlers/index.d.ts +0 -1
  133. package/dist/server/rpc/handlers/index.js +0 -2
  134. package/dist/server/rpc/handlers/load-model/download-manager.js +4 -2
  135. package/dist/server/rpc/handlers/load-model/http.js +20 -18
  136. package/dist/server/rpc/handlers/load-model/hyperdrive.js +21 -19
  137. package/dist/server/rpc/handlers/load-model/resolve.js +7 -5
  138. package/dist/server/rpc/handlers/load-model-delegated.d.ts +2 -2
  139. package/dist/server/rpc/handlers/load-model-delegated.js +10 -8
  140. package/dist/server/rpc/handlers/load-model.js +55 -3
  141. package/dist/server/rpc/handlers/logging-stream.js +4 -4
  142. package/dist/server/rpc/handlers/provideHandler/connection.js +12 -10
  143. package/dist/server/rpc/handlers/provideHandler/handler.js +18 -16
  144. package/dist/server/rpc/handlers/provideHandler/proxy.js +8 -6
  145. package/dist/server/rpc/handlers/rag.js +3 -1
  146. package/dist/server/rpc/handlers/stopProvideHandler.js +3 -1
  147. package/dist/server/rpc/handlers/transcribe-stream.js +3 -1
  148. package/dist/server/rpc/handlers/translate.js +3 -1
  149. package/dist/server/rpc/handlers/unload-model.js +4 -2
  150. package/dist/server/utils/audio/decoder.d.ts +2 -1
  151. package/dist/server/utils/audio/decoder.js +49 -12
  152. package/dist/server/utils/cache.js +7 -5
  153. package/dist/server/utils/config-transform.d.ts +3 -0
  154. package/dist/server/utils/config-transform.js +21 -0
  155. package/dist/server/utils/index.d.ts +1 -0
  156. package/dist/server/utils/index.js +1 -0
  157. package/dist/server/worker.js +41 -16
  158. package/dist/utils/errors-client.d.ts +12 -0
  159. package/dist/utils/errors-client.js +20 -0
  160. package/dist/utils/errors-server.d.ts +9 -0
  161. package/dist/utils/errors-server.js +16 -0
  162. package/dist/utils/getProcessSafe.d.ts +7 -0
  163. package/dist/utils/getProcessSafe.js +17 -0
  164. package/dist/utils/mcp-adapter.d.ts +12 -0
  165. package/dist/utils/mcp-adapter.js +103 -0
  166. package/dist/utils/object.d.ts +2 -0
  167. package/dist/utils/object.js +3 -0
  168. package/dist/utils/runtime.d.ts +30 -0
  169. package/dist/utils/runtime.js +48 -0
  170. package/dist/utils/tool-helpers.d.ts +10 -2
  171. package/dist/utils/tool-helpers.js +24 -11
  172. package/package.json +47 -34
  173. package/dist/client/api/set-config.d.ts +0 -7
  174. package/dist/client/api/set-config.js +0 -20
  175. package/dist/client/config-manager.d.ts +0 -4
  176. package/dist/client/config-manager.js +0 -8
  177. package/dist/examples/llamacpp-file-logging.d.ts +0 -2
  178. package/dist/schemas/set-config.d.ts +0 -21
  179. package/dist/schemas/set-config.js +0 -14
  180. package/dist/server/rpc/handlers/set-config.d.ts +0 -3
  181. package/dist/server/rpc/handlers/set-config.js +0 -18
@@ -1,51 +1,53 @@
1
1
  import { getSwarm, registerProviderTopic } from "../../../bare/hyperswarm.js";
2
2
  import { setupConnectionHandlers } from "./connection.js";
3
+ import { getServerLogger } from "../../../../logging/index.js";
4
+ const logger = getServerLogger();
3
5
  export async function provideHandler(request) {
4
6
  const swarm = getSwarm({
5
7
  firewallConfig: request.firewall,
6
8
  });
7
- console.log("🚀 Provide request received:", request);
8
- console.log("🔍 Swarm keyPair exists:", !!swarm.keyPair);
9
- console.log("🔍 Swarm publicKey:", swarm.keyPair?.publicKey?.toString("hex")?.substring(0, 16));
9
+ logger.debug("🚀 Provide request received:", request);
10
+ logger.debug("🔍 Swarm keyPair exists:", !!swarm.keyPair);
11
+ logger.debug("🔍 Swarm publicKey:", swarm.keyPair?.publicKey?.toString("hex")?.substring(0, 16));
10
12
  try {
11
- console.log("⚡ Starting provide handler execution");
13
+ logger.debug("⚡ Starting provide handler execution");
12
14
  const pubKey = swarm.keyPair.publicKey;
13
- console.log("🔑 Got public key:", pubKey.toString("hex"));
15
+ logger.debug("🔑 Got public key:", pubKey.toString("hex"));
14
16
  // Use provided topic from hex string
15
17
  const topic = Buffer.from(request.topic, "hex");
16
18
  // Join topic as server (provider)
17
- console.log("🌐 Joining topic as server...");
19
+ logger.info("🌐 Joining topic as server...");
18
20
  const discovery = swarm.join(topic, { server: true, client: false });
19
- console.log("📡 Discovery object created:", !!discovery);
21
+ logger.debug("📡 Discovery object created:", !!discovery);
20
22
  // Wait for the topic to be fully announced on the DHT
21
- console.log("⏳ Waiting for topic announcement...");
23
+ logger.debug("⏳ Waiting for topic announcement...");
22
24
  await discovery.flushed();
23
- console.log(`✅ Topic announced: ${topic.toString("hex")}`);
25
+ logger.info(`✅ Topic announced: ${topic.toString("hex")}`);
24
26
  // Wait for connections
25
- console.log("⏳ Waiting for swarm flush...");
27
+ logger.debug("⏳ Waiting for swarm flush...");
26
28
  await swarm.flush();
27
- console.log(`🎯 Ready to accept connections on topic: ${topic.toString("hex").substring(0, 16)}...`);
29
+ logger.info(`🎯 Ready to accept connections on topic: ${topic.toString("hex").substring(0, 16)}...`);
28
30
  // Handle incoming connections
29
31
  setupConnectionHandlers(swarm);
30
32
  registerProviderTopic(topic.toString("hex"));
31
- console.log("🏁 About to return success response...");
33
+ logger.debug("🏁 About to return success response...");
32
34
  const response = {
33
35
  type: "provide",
34
36
  success: true,
35
37
  publicKey: pubKey.toString("hex"),
36
38
  };
37
- console.log("📤 Returning response:", response);
39
+ logger.debug("📤 Returning response:", response);
38
40
  return response;
39
41
  }
40
42
  catch (error) {
41
- console.error("❌ Error in provide handler:", error);
42
- console.error("❌ Error stack:", error instanceof Error ? error.stack : "No stack trace");
43
+ logger.error("❌ Error in provide handler:", error);
44
+ logger.error("❌ Error stack:", error instanceof Error ? error.stack : "No stack trace");
43
45
  const errorResponse = {
44
46
  type: "provide",
45
47
  success: false,
46
48
  error: error instanceof Error ? error.message : "Unknown error",
47
49
  };
48
- console.log("📤 Returning error response:", errorResponse);
50
+ logger.debug("📤 Returning error response:", errorResponse);
49
51
  return errorResponse;
50
52
  }
51
53
  }
@@ -1,21 +1,23 @@
1
1
  import { handleRequest } from "../../handle-request.js";
2
+ import { getServerLogger } from "../../../../logging/index.js";
3
+ const logger = getServerLogger();
2
4
  // Proxies RPC requests to the main handler: handleRequest
3
5
  export function createRpcProxy() {
4
6
  return async (rpcRequest) => {
5
- console.log("📬 RPC request callback triggered!");
6
- console.log("📦 Raw RPC request data:", rpcRequest.data?.toString());
7
+ logger.debug("📬 RPC request callback triggered!");
8
+ logger.debug("📦 Raw RPC request data:", rpcRequest.data?.toString());
7
9
  try {
8
- console.log("🚀 Calling handleRequest...");
10
+ logger.debug("🚀 Calling handleRequest...");
9
11
  await handleRequest(rpcRequest);
10
- console.log("✅ handleRequest completed successfully");
12
+ logger.debug("✅ handleRequest completed successfully");
11
13
  }
12
14
  catch (error) {
13
- console.error("❌ Error:", error instanceof Error ? error.message : error);
15
+ logger.error("❌ Error:", error instanceof Error ? error.message : error);
14
16
  const errorResponse = JSON.stringify({
15
17
  type: "error",
16
18
  error: error instanceof Error ? error.message : "Unknown error",
17
19
  });
18
- console.log("📤 Sending error response:", errorResponse);
20
+ logger.debug("📤 Sending error response:", errorResponse);
19
21
  rpcRequest.reply(errorResponse, "utf-8");
20
22
  }
21
23
  };
@@ -1,4 +1,6 @@
1
1
  import { saveEmbeddings, search, deleteEmbeddings, } from "../../bare/rag-hyperdb/index.js";
2
+ import { getServerLogger } from "../../../logging/index.js";
3
+ const logger = getServerLogger();
2
4
  export async function handleRag(request) {
3
5
  try {
4
6
  switch (request.operation) {
@@ -32,7 +34,7 @@ export async function handleRag(request) {
32
34
  }
33
35
  }
34
36
  catch (error) {
35
- console.error("Error in RAG handler:", error);
37
+ logger.error("Error in RAG handler:", error);
36
38
  const baseError = {
37
39
  type: "rag",
38
40
  success: false,
@@ -1,4 +1,6 @@
1
1
  import { getSwarm, unregisterProviderTopic } from "../../bare/hyperswarm.js";
2
+ import { getServerLogger } from "../../../logging/index.js";
3
+ const logger = getServerLogger();
2
4
  export function stopProvideHandler(request) {
3
5
  const swarm = getSwarm();
4
6
  try {
@@ -12,7 +14,7 @@ export function stopProvideHandler(request) {
12
14
  };
13
15
  }
14
16
  catch (error) {
15
- console.error("❌ Error in stop provide handler:", error);
17
+ logger.error("❌ Error in stop provide handler:", error);
16
18
  return {
17
19
  type: "stopProvide",
18
20
  success: false,
@@ -1,4 +1,6 @@
1
1
  import { transcribeStream } from "../../bare/addons/whispercpp/index.js";
2
+ import { getServerLogger } from "../../../logging/index.js";
3
+ const logger = getServerLogger();
2
4
  export async function* handleTranscribeStream(request) {
3
5
  const { modelId, audioChunk, prompt } = request;
4
6
  try {
@@ -20,7 +22,7 @@ export async function* handleTranscribeStream(request) {
20
22
  };
21
23
  }
22
24
  catch (error) {
23
- console.error("Error during transcription:", error);
25
+ logger.error("Error during transcription:", error);
24
26
  yield {
25
27
  type: "transcribeStream",
26
28
  text: "",
@@ -1,4 +1,6 @@
1
1
  import { translate } from "../../bare/addons/translation/index.js";
2
+ import { getServerLogger } from "../../../logging/index.js";
3
+ const logger = getServerLogger();
2
4
  export async function* handleTranslate(request) {
3
5
  const { modelId, text, stream, modelType } = request;
4
6
  const from = request.modelType === "llm" ? request.from : undefined;
@@ -41,7 +43,7 @@ export async function* handleTranslate(request) {
41
43
  };
42
44
  }
43
45
  catch (error) {
44
- console.error("Error during translation:", error);
46
+ logger.error("Error during translation:", error);
45
47
  yield {
46
48
  type: "translate",
47
49
  token: "",
@@ -1,10 +1,12 @@
1
1
  import { unloadModel } from "../../bare/addons/index.js";
2
2
  import { getRegistryStats } from "../../bare/registry/model-registry.js";
3
3
  import { hasActiveProviders } from "../../bare/hyperswarm.js";
4
+ import { getServerLogger } from "../../../logging/index.js";
5
+ const logger = getServerLogger();
4
6
  export async function handleUnloadModel(request) {
5
7
  const { modelId, clearStorage } = request;
6
8
  try {
7
- console.log("Unloading model", modelId);
9
+ logger.debug("Unloading model", modelId);
8
10
  await unloadModel({ modelId, clearStorage });
9
11
  const stats = getRegistryStats();
10
12
  const modelsActive = stats.totalModels > 0;
@@ -17,7 +19,7 @@ export async function handleUnloadModel(request) {
17
19
  };
18
20
  }
19
21
  catch (error) {
20
- console.error("Error during model unload:", error);
22
+ logger.error("Error during model unload:", error);
21
23
  return {
22
24
  type: "unloadModel",
23
25
  success: false,
@@ -1,4 +1,5 @@
1
1
  import { Readable } from "bare-stream";
2
+ import { type AudioFormat } from "../../../schemas/index";
2
3
  export declare function needsDecoding(filePath: string): boolean;
3
- export declare function decodeAudioToStream(inputPath: string): Promise<Readable>;
4
+ export declare function decodeAudioToStream(inputPath: string, audioFormat?: AudioFormat): Promise<Readable>;
4
5
  //# sourceMappingURL=decoder.d.ts.map
@@ -1,17 +1,20 @@
1
1
  import fs from "bare-fs";
2
2
  import path from "bare-path";
3
- import GSTDecoder from "@qvac/decoder-audio";
3
+ import { FFmpegDecoder } from "@qvac/decoder-audio";
4
+ import { FORMATS_NEEDING_DECODE } from "@qvac/decoder-audio/constants.js";
4
5
  import { Readable } from "bare-stream";
5
- import { FORMATS_NEEDING_DECODE } from "../../../constants/audio.js";
6
+ import { getServerLogger } from "../../../logging/index.js";
7
+ import {} from "../../../schemas/index.js";
8
+ const logger = getServerLogger();
6
9
  export function needsDecoding(filePath) {
7
10
  const ext = path.extname(filePath).toLowerCase();
8
11
  return FORMATS_NEEDING_DECODE.includes(ext);
9
12
  }
10
- export async function decodeAudioToStream(inputPath) {
11
- const decoder = new GSTDecoder({
12
- config: {
13
- audioFormat: "encoded",
14
- },
13
+ const DECODER_TIMEOUT_MS = 10000;
14
+ export async function decodeAudioToStream(inputPath, audioFormat = "s16le") {
15
+ const decoder = new FFmpegDecoder({
16
+ config: { audioFormat },
17
+ logger,
15
18
  });
16
19
  try {
17
20
  await decoder.load();
@@ -20,22 +23,56 @@ export async function decodeAudioToStream(inputPath) {
20
23
  const outputStream = new Readable({
21
24
  read() { },
22
25
  });
26
+ let hasReceivedData = false;
27
+ let hasEnded = false;
28
+ // Fallback timeout in case the decoder hangs without emitting any events
29
+ const timeoutId = setTimeout(() => {
30
+ if (!hasEnded) {
31
+ hasEnded = true;
32
+ const timeoutError = new Error(`Audio decoding timed out after ${DECODER_TIMEOUT_MS}ms for file: ${inputPath}`);
33
+ outputStream.destroy(timeoutError);
34
+ }
35
+ }, DECODER_TIMEOUT_MS);
23
36
  response
24
37
  .onUpdate((output) => {
38
+ hasReceivedData = true;
25
39
  const bytes = new Uint8Array(output.outputArray);
26
40
  outputStream.push(Buffer.from(bytes));
27
41
  })
28
42
  .onFinish(() => {
29
- outputStream.push(null);
43
+ if (!hasEnded) {
44
+ hasEnded = true;
45
+ clearTimeout(timeoutId);
46
+ setImmediate(() => void decoder.unload());
47
+ if (!hasReceivedData) {
48
+ outputStream.destroy(new Error(`No audio data decoded from file: ${inputPath}`));
49
+ }
50
+ else {
51
+ outputStream.push(null);
52
+ }
53
+ }
30
54
  })
31
- .await()
32
- .catch((error) => {
33
- outputStream.destroy(error instanceof Error ? error : new Error(String(error)));
55
+ .onError((errorMessage) => {
56
+ if (!hasEnded) {
57
+ hasEnded = true;
58
+ clearTimeout(timeoutId);
59
+ setImmediate(() => void decoder.unload());
60
+ outputStream.destroy(new Error(errorMessage));
61
+ }
62
+ });
63
+ response.await().catch((error) => {
64
+ if (!hasEnded) {
65
+ hasEnded = true;
66
+ clearTimeout(timeoutId);
67
+ setImmediate(() => void decoder.unload());
68
+ outputStream.destroy(error instanceof Error ? error : new Error(String(error)));
69
+ }
34
70
  });
35
71
  return outputStream;
36
72
  }
37
73
  catch (error) {
38
- console.error("Decoding failed:", error instanceof Error ? error.message : String(error));
74
+ await decoder.unload();
75
+ logger.error("Decoding failed:", error instanceof Error ? error.message : String(error));
39
76
  throw error;
40
77
  }
41
78
  }
@@ -3,6 +3,8 @@ import path from "bare-path";
3
3
  import { getEnv } from "../worker.js";
4
4
  import { getConfiguredCacheDir } from "../bare/registry/config-registry.js";
5
5
  import { calculateFileChecksum } from "./checksum.js";
6
+ import { getServerLogger } from "../../logging/index.js";
7
+ const logger = getServerLogger();
6
8
  export const getCacheDir = (subDir) => {
7
9
  const homeDir = getEnv().HOME_DIR;
8
10
  const cacheDir = path.join(homeDir, ".qvac", subDir);
@@ -10,7 +12,7 @@ export const getCacheDir = (subDir) => {
10
12
  fs.mkdirSync(cacheDir, { recursive: true });
11
13
  }
12
14
  catch (error) {
13
- console.error(`Error creating cache directory (${subDir}):`, error instanceof Error ? error.message : String(error));
15
+ logger.error(`Error creating cache directory (${subDir}):`, error instanceof Error ? error.message : String(error));
14
16
  }
15
17
  return cacheDir;
16
18
  };
@@ -20,7 +22,7 @@ export const getModelsCacheDir = () => {
20
22
  fs.mkdirSync(configuredDir, { recursive: true });
21
23
  }
22
24
  catch (error) {
23
- console.error(`Error creating models cache directory:`, error instanceof Error ? error.message : String(error));
25
+ logger.error(`Error creating models cache directory:`, error instanceof Error ? error.message : String(error));
24
26
  }
25
27
  return configuredDir;
26
28
  };
@@ -38,7 +40,7 @@ export function getShardedModelCacheDir(hyperdriveKey) {
38
40
  fs.mkdirSync(shardDir, { recursive: true });
39
41
  }
40
42
  catch (error) {
41
- console.error(`Error creating sharded model cache directory:`, error instanceof Error ? error.message : String(error));
43
+ logger.error(`Error creating sharded model cache directory:`, error instanceof Error ? error.message : String(error));
42
44
  }
43
45
  return shardDir;
44
46
  }
@@ -66,14 +68,14 @@ export async function checkShardCompleteness(hyperdriveKey, shardFilenames, shar
66
68
  try {
67
69
  const stats = await fsPromises.stat(shardPath);
68
70
  if (stats.size !== fileMeta.expectedSize) {
69
- console.warn(`File ${i + 1} size mismatch: expected ${fileMeta.expectedSize}, got ${stats.size}`);
71
+ logger.warn(`File ${i + 1} size mismatch: expected ${fileMeta.expectedSize}, got ${stats.size}`);
70
72
  invalidIndices.push(i);
71
73
  continue;
72
74
  }
73
75
  if (fileMeta.sha256Checksum) {
74
76
  const actualChecksum = await calculateFileChecksum(shardPath);
75
77
  if (actualChecksum !== fileMeta.sha256Checksum) {
76
- console.warn(`File ${i + 1} checksum mismatch for ${fileMeta.filename}. Expected: ${fileMeta.sha256Checksum}. Actual: ${actualChecksum}. Will re-download.`);
78
+ logger.warn(`File ${i + 1} checksum mismatch for ${fileMeta.filename}. Expected: ${fileMeta.sha256Checksum}. Actual: ${actualChecksum}. Will re-download.`);
77
79
  invalidIndices.push(i);
78
80
  }
79
81
  }
@@ -0,0 +1,3 @@
1
+ import type { ModelType } from "../../schemas/index";
2
+ export declare function transformConfigForReload(modelType: ModelType, config: unknown): unknown;
3
+ //# sourceMappingURL=config-transform.d.ts.map
@@ -0,0 +1,21 @@
1
+ export function transformConfigForReload(modelType, config) {
2
+ switch (modelType) {
3
+ case "whisper": {
4
+ const whisperConfig = config;
5
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
6
+ const { contextParams, miscConfig, ...whisperParams } = whisperConfig;
7
+ return {
8
+ whisperConfig: whisperParams,
9
+ ...(miscConfig && { miscConfig }),
10
+ };
11
+ }
12
+ case "llm":
13
+ case "embeddings":
14
+ case "nmt":
15
+ case "tts":
16
+ // Return as-is for now
17
+ return config;
18
+ default:
19
+ return config;
20
+ }
21
+ }
@@ -1,6 +1,7 @@
1
1
  export * from "./audio/decoder";
2
2
  export * from "./cache";
3
3
  export * from "./checksum";
4
+ export * from "./config-transform";
4
5
  export * from "./hash";
5
6
  export * from "./model-path";
6
7
  export * from "./shard-utils";
@@ -1,6 +1,7 @@
1
1
  export * from "./audio/decoder.js";
2
2
  export * from "./cache.js";
3
3
  export * from "./checksum.js";
4
+ export * from "./config-transform.js";
4
5
  export * from "./hash.js";
5
6
  export * from "./model-path.js";
6
7
  export * from "./shard-utils.js";
@@ -5,9 +5,24 @@ import { destroySwarm } from "./bare/hyperswarm.js";
5
5
  import { closeAllRagInstances } from "./bare/rag-hyperdb/rag-manager.js";
6
6
  import { cleanupDownloads } from "./rpc/handlers/load-model/download-manager.js";
7
7
  import { unloadAllModels } from "./bare/registry/model-registry.js";
8
- import { clearAllLoggingStreams } from "./bare/registry/logging-stream-registry.js";
9
- console.log("🐻 Hello from Bare");
10
- console.log("Arguments to worker:", process.argv);
8
+ import { clearAllLoggingStreams, startLogBuffering, } from "./bare/registry/logging-stream-registry.js";
9
+ import { ADDON_NAMESPACES, createAddonLoggerCallback, clearAllAddonLoggers, getServerLogger, SDK_LOG_ID, } from "../logging/index.js";
10
+ import llmAddonLogging from "@qvac/llm-llamacpp/addonLogging.js";
11
+ import embedAddonLogging from "@qvac/embed-llamacpp/addonLogging.js";
12
+ import ttsAddonLogging from "@qvac/tts-onnx/addonLogging.js";
13
+ import whisperAddonLogging from "@qvac/transcription-whispercpp/addonLogging.js";
14
+ import nmtAddonLogging from "@qvac/translation-nmtcpp/addonLogging.js";
15
+ // Buffer SDK logs from startup so clients can receive them when they subscribe
16
+ startLogBuffering(SDK_LOG_ID);
17
+ const logger = getServerLogger();
18
+ logger.info("🐻 Hello from Bare");
19
+ logger.debug("Arguments to worker:", process.argv);
20
+ // Initialize addon logger callbacks
21
+ llmAddonLogging.setLogger(createAddonLoggerCallback(ADDON_NAMESPACES.LLAMACPP_LLM));
22
+ embedAddonLogging.setLogger(createAddonLoggerCallback(ADDON_NAMESPACES.LLAMACPP_EMBED));
23
+ ttsAddonLogging.setLogger(createAddonLoggerCallback(ADDON_NAMESPACES.TTS));
24
+ whisperAddonLogging.setLogger(createAddonLoggerCallback(ADDON_NAMESPACES.WHISPERCPP));
25
+ nmtAddonLogging.setLogger(createAddonLoggerCallback(ADDON_NAMESPACES.NMTCPP));
11
26
  const defaultHomeDir = process.env["HOME"] || process.env["USERPROFILE"] || "/tmp";
12
27
  let envConfig = { HOME_DIR: defaultHomeDir };
13
28
  let hasRPCConfig = false;
@@ -17,11 +32,11 @@ if (process.argv[2]) {
17
32
  const rpcArgs = JSON.parse(process.argv[2]);
18
33
  envConfig = { ...envConfig, ...rpcArgs };
19
34
  hasRPCConfig = true;
20
- console.log("Parsed RPC configuration from arguments");
35
+ logger.info("Parsed RPC configuration from arguments");
21
36
  }
22
37
  catch {
23
38
  // Not JSON or invalid - use defaults (direct mode)
24
- console.log("Using default configuration (direct mode)");
39
+ logger.info("Using default configuration (direct mode)");
25
40
  }
26
41
  }
27
42
  const validatedEnv = z
@@ -43,22 +58,22 @@ export function ensureRPCSetup() {
43
58
  try {
44
59
  const ipcSocketPath = validatedEnv.QVAC_IPC_SOCKET_PATH;
45
60
  if (ipcSocketPath) {
46
- console.log(`Running in desktop mode, connecting to IPC socket: ${ipcSocketPath}`);
61
+ logger.info(`Running in desktop mode, connecting to IPC socket: ${ipcSocketPath}`);
47
62
  // Connect to the IPC server (Named Pipe or Unix Socket)
48
63
  const rpc = createIPCClient(ipcSocketPath);
49
- console.log("Desktop IPC client created?", !!rpc);
64
+ logger.debug("Desktop IPC client created?", !!rpc);
50
65
  }
51
66
  else {
52
- console.log("Running in BareKit IPC mode");
67
+ logger.info("Running in BareKit IPC mode");
53
68
  // Start the standard RPC server with BareKit IPC for mobile
54
69
  createBareKitRPCServer();
55
70
  }
56
- console.log("Bare worker started and listening for RPC requests");
57
- console.log("Working directory:", process.cwd());
71
+ logger.info("Bare worker started and listening for RPC requests");
72
+ logger.debug("Working directory:", process.cwd());
58
73
  rpcInitialized = true;
59
74
  }
60
75
  catch (error) {
61
- console.error("Worker error:", error);
76
+ logger.error("Worker error:", error);
62
77
  process.exit(1);
63
78
  }
64
79
  }
@@ -67,7 +82,17 @@ if (hasRPCConfig) {
67
82
  ensureRPCSetup();
68
83
  }
69
84
  else {
70
- console.log("Running in direct mode - RPC setup will be lazy");
85
+ logger.info("Running in direct mode - RPC setup will be lazy");
86
+ }
87
+ // Centralized logger cleanup
88
+ function clearLoggers() {
89
+ clearAllLoggingStreams();
90
+ clearAllAddonLoggers();
91
+ llmAddonLogging.releaseLogger();
92
+ embedAddonLogging.releaseLogger();
93
+ ttsAddonLogging.releaseLogger();
94
+ whisperAddonLogging.releaseLogger();
95
+ nmtAddonLogging.releaseLogger();
71
96
  }
72
97
  // Centralized cleanup for graceful shutdown
73
98
  let isShuttingDown = false;
@@ -75,19 +100,19 @@ const shutdownHandler = async () => {
75
100
  if (isShuttingDown)
76
101
  return;
77
102
  isShuttingDown = true;
78
- console.log("🐻 Bare worker shutdown signal received, cleaning up...");
103
+ logger.info("🐻 Bare worker shutdown signal received, cleaning up...");
79
104
  try {
80
- clearAllLoggingStreams();
105
+ clearLoggers();
81
106
  await Promise.allSettled([
82
107
  destroySwarm(),
83
108
  closeAllRagInstances(),
84
109
  cleanupDownloads(),
85
110
  unloadAllModels(),
86
111
  ]);
87
- console.log("✅ Cleanup completed successfully");
112
+ logger.info("✅ Cleanup completed successfully");
88
113
  }
89
114
  catch (error) {
90
- console.error("❌ Error during shutdown cleanup:", error);
115
+ logger.error("❌ Error during shutdown cleanup:", error);
91
116
  }
92
117
  process.exit(0);
93
118
  };
@@ -56,6 +56,18 @@ export declare class SDKNotFoundInNodeModulesError extends QvacErrorBase {
56
56
  export declare class WorkerFileNotFoundError extends QvacErrorBase {
57
57
  constructor(workerPath: string, cause?: unknown);
58
58
  }
59
+ export declare class ConfigFileNotFoundError extends QvacErrorBase {
60
+ constructor(searchPaths: string, cause?: unknown);
61
+ }
62
+ export declare class ConfigFileInvalidError extends QvacErrorBase {
63
+ constructor(filePath: string, reason: string, cause?: unknown);
64
+ }
65
+ export declare class ConfigFileParseFailedError extends QvacErrorBase {
66
+ constructor(filePath: string, error: string, cause?: unknown);
67
+ }
68
+ export declare class ConfigValidationFailedError extends QvacErrorBase {
69
+ constructor(errors: string, cause?: unknown);
70
+ }
59
71
  export declare class ModelUnloadFailedError extends QvacErrorBase {
60
72
  constructor(modelId?: string, cause?: unknown);
61
73
  }
@@ -100,6 +100,26 @@ export class WorkerFileNotFoundError extends QvacErrorBase {
100
100
  super(createErrorOptions(SDK_CLIENT_ERROR_CODES.WORKER_FILE_NOT_FOUND, [workerPath], cause));
101
101
  }
102
102
  }
103
+ export class ConfigFileNotFoundError extends QvacErrorBase {
104
+ constructor(searchPaths, cause) {
105
+ super(createErrorOptions(SDK_CLIENT_ERROR_CODES.CONFIG_FILE_NOT_FOUND, [searchPaths], cause));
106
+ }
107
+ }
108
+ export class ConfigFileInvalidError extends QvacErrorBase {
109
+ constructor(filePath, reason, cause) {
110
+ super(createErrorOptions(SDK_CLIENT_ERROR_CODES.CONFIG_FILE_INVALID, [filePath, reason], cause));
111
+ }
112
+ }
113
+ export class ConfigFileParseFailedError extends QvacErrorBase {
114
+ constructor(filePath, error, cause) {
115
+ super(createErrorOptions(SDK_CLIENT_ERROR_CODES.CONFIG_FILE_PARSE_FAILED, [filePath, error], cause));
116
+ }
117
+ }
118
+ export class ConfigValidationFailedError extends QvacErrorBase {
119
+ constructor(errors, cause) {
120
+ super(createErrorOptions(SDK_CLIENT_ERROR_CODES.CONFIG_VALIDATION_FAILED, [errors], cause));
121
+ }
122
+ }
103
123
  // ============== Operation Errors (Client-side wrappers for server operations) ==============
104
124
  // These are used by client API to throw errors based on server responses
105
125
  // They reference server error codes but are thrown on client side
@@ -68,6 +68,12 @@ export declare class CancelFailedError extends QvacErrorBase {
68
68
  export declare class TextToSpeechFailedError extends QvacErrorBase {
69
69
  constructor(details?: string, cause?: unknown);
70
70
  }
71
+ export declare class ConfigReloadNotSupportedError extends QvacErrorBase {
72
+ constructor(modelId: string, cause?: unknown);
73
+ }
74
+ export declare class ModelTypeMismatchError extends QvacErrorBase {
75
+ constructor(expectedType: string, providedType: string, cause?: unknown);
76
+ }
71
77
  export declare class RAGSaveFailedError extends QvacErrorBase {
72
78
  constructor(details?: string, cause?: unknown);
73
79
  }
@@ -125,6 +131,9 @@ export declare class CacheDirNotAbsoluteError extends QvacErrorBase {
125
131
  export declare class CacheDirNotWritableError extends QvacErrorBase {
126
132
  constructor(cacheDir: string, details?: string, cause?: unknown);
127
133
  }
134
+ export declare class ConfigAlreadySetError extends QvacErrorBase {
135
+ constructor(cause?: unknown);
136
+ }
128
137
  export declare class FFmpegNotAvailableError extends QvacErrorBase {
129
138
  constructor(cause?: unknown);
130
139
  }
@@ -120,6 +120,16 @@ export class TextToSpeechFailedError extends QvacErrorBase {
120
120
  super(createErrorOptions(SDK_SERVER_ERROR_CODES.TEXT_TO_SPEECH_FAILED, details ? [details] : undefined, cause));
121
121
  }
122
122
  }
123
+ export class ConfigReloadNotSupportedError extends QvacErrorBase {
124
+ constructor(modelId, cause) {
125
+ super(createErrorOptions(SDK_SERVER_ERROR_CODES.CONFIG_RELOAD_NOT_SUPPORTED, [modelId], cause));
126
+ }
127
+ }
128
+ export class ModelTypeMismatchError extends QvacErrorBase {
129
+ constructor(expectedType, providedType, cause) {
130
+ super(createErrorOptions(SDK_SERVER_ERROR_CODES.MODEL_TYPE_MISMATCH, [expectedType, providedType], cause));
131
+ }
132
+ }
123
133
  // ============== RAG Operation Errors ==============
124
134
  export class RAGSaveFailedError extends QvacErrorBase {
125
135
  constructor(details, cause) {
@@ -218,6 +228,12 @@ export class CacheDirNotWritableError extends QvacErrorBase {
218
228
  super(createErrorOptions(SDK_SERVER_ERROR_CODES.CACHE_DIR_NOT_WRITABLE, details ? [cacheDir, details] : [cacheDir], cause));
219
229
  }
220
230
  }
231
+ // ============== Config Operations Errors ==============
232
+ export class ConfigAlreadySetError extends QvacErrorBase {
233
+ constructor(cause) {
234
+ super(createErrorOptions(SDK_SERVER_ERROR_CODES.CONFIG_ALREADY_SET, undefined, cause));
235
+ }
236
+ }
221
237
  // ============== System/Runtime Errors ==============
222
238
  export class FFmpegNotAvailableError extends QvacErrorBase {
223
239
  constructor(cause) {
@@ -0,0 +1,7 @@
1
+ export declare function getProcessSafe(): Promise<{
2
+ cwd?: () => string;
3
+ env?: Record<string, string | undefined>;
4
+ platform?: string;
5
+ exit?: (code: number) => void;
6
+ } | undefined>;
7
+ //# sourceMappingURL=getProcessSafe.d.ts.map
@@ -0,0 +1,17 @@
1
+ import { detectRuntime } from "./runtime.js";
2
+ export async function getProcessSafe() {
3
+ const runtime = detectRuntime();
4
+ if (runtime === "bare") {
5
+ try {
6
+ const bareProcess = await import("bare-process");
7
+ return bareProcess.default;
8
+ }
9
+ catch {
10
+ return undefined;
11
+ }
12
+ }
13
+ if (typeof process !== "undefined") {
14
+ return process;
15
+ }
16
+ return undefined;
17
+ }
@@ -0,0 +1,12 @@
1
+ import type { Tool } from "../schemas/tools";
2
+ import type { McpClientInput } from "../schemas/mcp-adapter";
3
+ import type { ToolHandler } from "./tool-helpers";
4
+ export type { McpClient, McpClientInput } from "../schemas/mcp-adapter";
5
+ export type ToolHandlerMap = Map<string, ToolHandler>;
6
+ export type McpToolsResult = {
7
+ tools: Tool[];
8
+ handlers: ToolHandlerMap;
9
+ };
10
+ export declare function getMcpToolsWithHandlers(clients: McpClientInput[]): Promise<McpToolsResult>;
11
+ export declare function getMcpTools(clients: McpClientInput[]): Promise<Tool[]>;
12
+ //# sourceMappingURL=mcp-adapter.d.ts.map