@qvac/sdk 0.7.1 → 0.8.1

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 (257) hide show
  1. package/NOTICE +73 -10
  2. package/README.md +4 -4
  3. package/bare-imports.json +9 -0
  4. package/dist/client/api/cancel.d.ts +9 -0
  5. package/dist/client/api/cancel.js +9 -0
  6. package/dist/client/api/completion-stream.d.ts +2 -1
  7. package/dist/client/api/completion-stream.js +2 -1
  8. package/dist/client/api/download-asset.d.ts +3 -2
  9. package/dist/client/api/download-asset.js +4 -3
  10. package/dist/client/api/embed.d.ts +5 -2
  11. package/dist/client/api/embed.js +2 -2
  12. package/dist/client/api/get-model-info.d.ts +1 -1
  13. package/dist/client/api/heartbeat.d.ts +30 -0
  14. package/dist/client/api/heartbeat.js +38 -0
  15. package/dist/client/api/index.d.ts +1 -1
  16. package/dist/client/api/index.js +1 -1
  17. package/dist/client/api/invoke-plugin.d.ts +3 -2
  18. package/dist/client/api/invoke-plugin.js +4 -4
  19. package/dist/client/api/load-model.d.ts +12 -10
  20. package/dist/client/api/load-model.js +3 -3
  21. package/dist/client/api/rag.d.ts +10 -10
  22. package/dist/client/api/rag.js +21 -21
  23. package/dist/client/api/text-to-speech.d.ts +2 -2
  24. package/dist/client/api/text-to-speech.js +3 -3
  25. package/dist/client/api/transcribe.d.ts +5 -3
  26. package/dist/client/api/transcribe.js +6 -4
  27. package/dist/client/api/translate.d.ts +2 -2
  28. package/dist/client/api/translate.js +3 -3
  29. package/dist/client/rpc/node-rpc-client.d.ts +2 -7
  30. package/dist/client/rpc/node-rpc-client.js +2 -39
  31. package/dist/client/rpc/profiling/index.d.ts +2 -0
  32. package/dist/client/rpc/profiling/index.js +1 -0
  33. package/dist/client/rpc/profiling/profiler.d.ts +27 -0
  34. package/dist/client/rpc/profiling/profiler.js +139 -0
  35. package/dist/client/rpc/rpc-client.d.ts +2 -2
  36. package/dist/client/rpc/rpc-client.js +174 -12
  37. package/dist/examples/delegated-inference/consumer-profiled.d.ts +2 -0
  38. package/dist/examples/delegated-inference/consumer-profiled.js +67 -0
  39. package/dist/examples/embed-p2p.d.ts +2 -0
  40. package/dist/examples/llamacpp-multimodal.js +1 -1
  41. package/dist/examples/llamacpp-p2p.d.ts +2 -0
  42. package/dist/examples/parallel-download.js +45 -13
  43. package/dist/examples/profiling/basic.d.ts +2 -0
  44. package/dist/examples/profiling/basic.js +71 -0
  45. package/dist/examples/profiling/per-call.d.ts +2 -0
  46. package/dist/examples/profiling/per-call.js +30 -0
  47. package/dist/examples/seed-p2p.d.ts +2 -0
  48. package/dist/examples/transcription/parakeet-ctc-filesystem.d.ts +2 -0
  49. package/dist/examples/transcription/parakeet-ctc-filesystem.js +40 -0
  50. package/dist/examples/transcription/parakeet-microphone-record.d.ts +2 -0
  51. package/dist/examples/transcription/parakeet-microphone-record.js +95 -0
  52. package/dist/examples/transcription/parakeet-sortformer.d.ts +2 -0
  53. package/dist/examples/transcription/parakeet-sortformer.js +115 -0
  54. package/dist/examples/transcription/parakeet-tdt-filesystem.d.ts +2 -0
  55. package/dist/examples/transcription/parakeet-tdt-filesystem.js +44 -0
  56. package/dist/examples/translation/translation-bergamot-pivot.d.ts +2 -0
  57. package/dist/examples/translation/translation-bergamot-pivot.js +73 -0
  58. package/dist/examples/translation/translation-llm-afriquegemma.d.ts +2 -0
  59. package/dist/examples/translation/translation-llm-afriquegemma.js +39 -0
  60. package/dist/index.d.ts +4 -2
  61. package/dist/index.js +3 -1
  62. package/dist/logging/index.d.ts +1 -1
  63. package/dist/logging/index.js +1 -1
  64. package/dist/logging/namespaces.d.ts +3 -9
  65. package/dist/logging/namespaces.js +2 -8
  66. package/dist/logging/registry.js +15 -1
  67. package/dist/models/registry/models.d.ts +1671 -310
  68. package/dist/models/registry/models.js +2116 -710
  69. package/dist/models/update-models/codegen.js +2 -2
  70. package/dist/models/update-models/history.d.ts +11 -0
  71. package/dist/models/update-models/history.js +24 -5
  72. package/dist/models/update-models/index.js +17 -16
  73. package/dist/models/update-models/naming.js +56 -0
  74. package/dist/profiling/aggregator.d.ts +15 -0
  75. package/dist/profiling/aggregator.js +100 -0
  76. package/dist/profiling/clock.d.ts +12 -0
  77. package/dist/profiling/clock.js +51 -0
  78. package/dist/profiling/controller.d.ts +33 -0
  79. package/dist/profiling/controller.js +123 -0
  80. package/dist/profiling/envelope.d.ts +10 -0
  81. package/dist/profiling/envelope.js +36 -0
  82. package/dist/profiling/events.d.ts +20 -0
  83. package/dist/profiling/events.js +37 -0
  84. package/dist/profiling/exporters.d.ts +10 -0
  85. package/dist/profiling/exporters.js +236 -0
  86. package/dist/profiling/index.d.ts +36 -0
  87. package/dist/profiling/index.js +31 -0
  88. package/dist/profiling/ring-buffer.d.ts +19 -0
  89. package/dist/profiling/ring-buffer.js +83 -0
  90. package/dist/profiling/types.d.ts +47 -0
  91. package/dist/profiling/types.js +1 -0
  92. package/dist/schemas/cancel.d.ts +12 -0
  93. package/dist/schemas/cancel.js +2 -0
  94. package/dist/schemas/common.d.ts +1927 -135
  95. package/dist/schemas/common.js +6 -3
  96. package/dist/schemas/completion-stream.d.ts +31 -0
  97. package/dist/schemas/completion-stream.js +13 -0
  98. package/dist/schemas/delegate.d.ts +8 -0
  99. package/dist/schemas/delegate.js +5 -2
  100. package/dist/schemas/download-asset.d.ts +14 -3
  101. package/dist/schemas/download-asset.js +3 -1
  102. package/dist/schemas/engine-addon-map.js +9 -6
  103. package/dist/schemas/get-model-info.d.ts +2 -0
  104. package/dist/schemas/get-model-info.js +1 -0
  105. package/dist/schemas/heartbeat.d.ts +17 -0
  106. package/dist/schemas/heartbeat.js +10 -0
  107. package/dist/schemas/index.d.ts +3 -2
  108. package/dist/schemas/index.js +3 -2
  109. package/dist/schemas/llamacpp-config.d.ts +140 -14
  110. package/dist/schemas/llamacpp-config.js +11 -7
  111. package/dist/schemas/load-model.d.ts +9762 -2515
  112. package/dist/schemas/load-model.js +142 -182
  113. package/dist/schemas/model-src-utils.d.ts +10 -2
  114. package/dist/schemas/model-types.d.ts +19 -1
  115. package/dist/schemas/model-types.js +11 -0
  116. package/dist/schemas/ocr.d.ts +37 -0
  117. package/dist/schemas/ocr.js +5 -0
  118. package/dist/schemas/plugin.d.ts +51 -5
  119. package/dist/schemas/plugin.js +26 -0
  120. package/dist/schemas/profiling.d.ts +105 -0
  121. package/dist/schemas/profiling.js +66 -0
  122. package/dist/schemas/registry.d.ts +18 -0
  123. package/dist/schemas/registry.js +2 -0
  124. package/dist/schemas/reload-config.d.ts +126 -6
  125. package/dist/schemas/reload-config.js +1 -1
  126. package/dist/schemas/sdk-config.d.ts +2280 -24
  127. package/dist/schemas/sdk-config.js +6 -1
  128. package/dist/schemas/sdk-errors-client.d.ts +1 -0
  129. package/dist/schemas/sdk-errors-client.js +7 -0
  130. package/dist/schemas/sdk-errors-server.d.ts +3 -0
  131. package/dist/schemas/sdk-errors-server.js +15 -0
  132. package/dist/schemas/text-to-speech.d.ts +90 -68
  133. package/dist/schemas/text-to-speech.js +16 -33
  134. package/dist/schemas/transcription-config.d.ts +383 -0
  135. package/dist/schemas/{whispercpp-config.js → transcription-config.js} +29 -1
  136. package/dist/schemas/translation-config.d.ts +463 -8
  137. package/dist/schemas/translation-config.js +35 -2
  138. package/dist/server/bare/delegate-rpc-client.js +52 -11
  139. package/dist/server/bare/ops/load-model.d.ts +7 -1
  140. package/dist/server/bare/ops/load-model.js +41 -42
  141. package/dist/server/bare/ops/transcribe.d.ts +3 -0
  142. package/dist/server/bare/ops/transcribe.js +75 -0
  143. package/dist/server/bare/ops/translate.d.ts +2 -0
  144. package/dist/server/bare/ops/translate.js +12 -4
  145. package/dist/server/bare/plugins/index.d.ts +1 -0
  146. package/dist/server/bare/plugins/index.js +1 -0
  147. package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stream.d.ts +2 -1
  148. package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stream.js +8 -6
  149. package/dist/server/bare/plugins/llamacpp-completion/plugin.d.ts +108 -3
  150. package/dist/server/bare/plugins/llamacpp-completion/plugin.js +19 -6
  151. package/dist/server/bare/plugins/llamacpp-embedding/plugin.d.ts +32 -2
  152. package/dist/server/bare/plugins/llamacpp-embedding/plugin.js +31 -17
  153. package/dist/server/bare/plugins/nmtcpp-translation/plugin.d.ts +325 -3
  154. package/dist/server/bare/plugins/nmtcpp-translation/plugin.js +117 -13
  155. package/dist/server/bare/plugins/onnx-ocr/plugin.d.ts +50 -2
  156. package/dist/server/bare/plugins/onnx-ocr/plugin.js +46 -5
  157. package/dist/server/bare/plugins/onnx-tts/plugin.d.ts +351 -4
  158. package/dist/server/bare/plugins/onnx-tts/plugin.js +81 -61
  159. package/dist/server/bare/plugins/parakeet-transcription/plugin.d.ts +317 -0
  160. package/dist/server/bare/plugins/parakeet-transcription/plugin.js +154 -0
  161. package/dist/server/bare/plugins/whispercpp-transcription/plugin.d.ts +209 -3
  162. package/dist/server/bare/plugins/whispercpp-transcription/plugin.js +21 -9
  163. package/dist/server/bare/rag-hyperdb/rag-workspace-manager.js +2 -2
  164. package/dist/server/bare/registry/model-config-utils.js +3 -1
  165. package/dist/server/bare/registry/model-registry.d.ts +2 -0
  166. package/dist/server/bare/registry/model-registry.js +2 -1
  167. package/dist/server/bare/utils/audio-input.d.ts +10 -0
  168. package/dist/server/bare/utils/audio-input.js +33 -0
  169. package/dist/server/error-handlers.d.ts +3 -2
  170. package/dist/server/error-handlers.js +11 -8
  171. package/dist/server/plugins/registry.js +5 -1
  172. package/dist/server/rpc/delegate-transport.d.ts +11 -3
  173. package/dist/server/rpc/delegate-transport.js +214 -38
  174. package/dist/server/rpc/delegate-utils.d.ts +2 -0
  175. package/dist/server/rpc/delegate-utils.js +5 -0
  176. package/dist/server/rpc/handle-request.js +43 -4
  177. package/dist/server/rpc/handler-registry.js +33 -4
  178. package/dist/server/rpc/handler-utils.d.ts +5 -4
  179. package/dist/server/rpc/handler-utils.js +114 -31
  180. package/dist/server/rpc/handlers/cancel-delegated.d.ts +4 -0
  181. package/dist/server/rpc/handlers/cancel-delegated.js +71 -0
  182. package/dist/server/rpc/handlers/completion-stream-delegated.d.ts +3 -1
  183. package/dist/server/rpc/handlers/completion-stream-delegated.js +13 -4
  184. package/dist/server/rpc/handlers/download-asset.js +55 -3
  185. package/dist/server/rpc/handlers/heartbeat-delegated.d.ts +4 -0
  186. package/dist/server/rpc/handlers/heartbeat-delegated.js +32 -0
  187. package/dist/server/rpc/handlers/heartbeat.d.ts +3 -0
  188. package/dist/server/rpc/handlers/heartbeat.js +3 -0
  189. package/dist/server/rpc/handlers/index.d.ts +2 -2
  190. package/dist/server/rpc/handlers/index.js +2 -2
  191. package/dist/server/rpc/handlers/load-model/download-stats.d.ts +6 -0
  192. package/dist/server/rpc/handlers/load-model/download-stats.js +87 -0
  193. package/dist/server/rpc/handlers/load-model/handler.js +108 -123
  194. package/dist/server/rpc/handlers/load-model/http.d.ts +2 -1
  195. package/dist/server/rpc/handlers/load-model/http.js +21 -5
  196. package/dist/server/rpc/handlers/load-model/hyperdrive.d.ts +2 -1
  197. package/dist/server/rpc/handlers/load-model/hyperdrive.js +19 -14
  198. package/dist/server/rpc/handlers/load-model/registry.d.ts +2 -1
  199. package/dist/server/rpc/handlers/load-model/registry.js +113 -136
  200. package/dist/server/rpc/handlers/load-model/resolve.d.ts +2 -0
  201. package/dist/server/rpc/handlers/load-model/resolve.js +55 -22
  202. package/dist/server/rpc/handlers/load-model/types.d.ts +29 -0
  203. package/dist/server/rpc/handlers/load-model/types.js +1 -0
  204. package/dist/server/rpc/handlers/load-model-delegated.d.ts +5 -1
  205. package/dist/server/rpc/handlers/load-model-delegated.js +41 -11
  206. package/dist/server/rpc/handlers/plugin-dispatch.js +15 -10
  207. package/dist/server/rpc/handlers/plugin-invoke.js +56 -51
  208. package/dist/server/rpc/handlers/rag.js +24 -0
  209. package/dist/server/rpc/handlers/unload-model-delegated.d.ts +3 -0
  210. package/dist/server/rpc/handlers/unload-model-delegated.js +32 -0
  211. package/dist/server/rpc/profiling/context.d.ts +18 -0
  212. package/dist/server/rpc/profiling/context.js +38 -0
  213. package/dist/server/rpc/profiling/delegation-profiler.d.ts +32 -0
  214. package/dist/server/rpc/profiling/delegation-profiler.js +154 -0
  215. package/dist/server/rpc/profiling/index.d.ts +5 -0
  216. package/dist/server/rpc/profiling/index.js +4 -0
  217. package/dist/server/rpc/profiling/operation-metrics.d.ts +25 -0
  218. package/dist/server/rpc/profiling/operation-metrics.js +199 -0
  219. package/dist/server/rpc/profiling/operation-wrappers.d.ts +18 -0
  220. package/dist/server/rpc/profiling/operation-wrappers.js +124 -0
  221. package/dist/server/rpc/profiling/profiler.d.ts +13 -0
  222. package/dist/server/rpc/profiling/profiler.js +97 -0
  223. package/dist/server/utils/cache.d.ts +2 -1
  224. package/dist/server/utils/cache.js +5 -1
  225. package/dist/server/utils/checksum.d.ts +2 -0
  226. package/dist/server/utils/checksum.js +7 -0
  227. package/dist/server/utils/formatting.d.ts +6 -0
  228. package/dist/server/utils/formatting.js +35 -0
  229. package/dist/server/worker.js +2 -1
  230. package/dist/utils/errors-client.d.ts +3 -0
  231. package/dist/utils/errors-client.js +6 -0
  232. package/dist/utils/errors-server.d.ts +9 -0
  233. package/dist/utils/errors-server.js +15 -0
  234. package/dist/utils/global-singleton.d.ts +2 -0
  235. package/dist/utils/global-singleton.js +10 -0
  236. package/package.json +22 -18
  237. package/dist/client/api/ping.d.ts +0 -11
  238. package/dist/client/api/ping.js +0 -19
  239. package/dist/examples/embed-hyperdrive.d.ts +0 -2
  240. package/dist/examples/llamacpp-hyperdrive.d.ts +0 -2
  241. package/dist/examples/seed-hyperdrive.d.ts +0 -2
  242. package/dist/schemas/ping.d.ts +0 -11
  243. package/dist/schemas/ping.js +0 -8
  244. package/dist/schemas/whispercpp-config.d.ts +0 -70
  245. package/dist/server/bare/plugins/whispercpp-transcription/ops/transcribe-stream.d.ts +0 -3
  246. package/dist/server/bare/plugins/whispercpp-transcription/ops/transcribe-stream.js +0 -81
  247. package/dist/server/rpc/handlers/ping.d.ts +0 -3
  248. package/dist/server/rpc/handlers/ping.js +0 -3
  249. /package/dist/examples/{embed-hyperdrive.js → embed-p2p.js} +0 -0
  250. /package/dist/examples/{llamacpp-hyperdrive.js → llamacpp-p2p.js} +0 -0
  251. /package/dist/examples/{seed-hyperdrive.js → seed-p2p.js} +0 -0
  252. /package/dist/examples/{whispercpp-filesystem.d.ts → transcription/whispercpp-filesystem.d.ts} +0 -0
  253. /package/dist/examples/{whispercpp-filesystem.js → transcription/whispercpp-filesystem.js} +0 -0
  254. /package/dist/examples/{whispercpp-microphone-record.d.ts → transcription/whispercpp-microphone-record.d.ts} +0 -0
  255. /package/dist/examples/{whispercpp-microphone-record.js → transcription/whispercpp-microphone-record.js} +0 -0
  256. /package/dist/examples/{whispercpp-prompt.d.ts → transcription/whispercpp-prompt.d.ts} +0 -0
  257. /package/dist/examples/{whispercpp-prompt.js → transcription/whispercpp-prompt.js} +0 -0
@@ -3,6 +3,8 @@ import RPC from "bare-rpc";
3
3
  import { withTimeout } from "../../utils/withTimeout.js";
4
4
  import { DelegateConnectionFailedError } from "../../utils/errors-server.js";
5
5
  import { getServerLogger } from "../../logging/index.js";
6
+ import { nowMs } from "../../profiling/index.js";
7
+ import { cacheDelegationConnectionTime, clearPeerConnectionTracking, } from "../rpc/profiling/delegation-profiler.js";
6
8
  const logger = getServerLogger();
7
9
  // Map of active RPC instances by public key
8
10
  const activeRPCs = new Map();
@@ -10,6 +12,26 @@ const activeRPCs = new Map();
10
12
  const activeConnections = new Map();
11
13
  // Track whether the global connection handler has been registered
12
14
  let connectionHandlerRegistered = false;
15
+ const HEALTH_CHECK_TIMEOUT_MS = 1500;
16
+ import { getNextCommandId } from "../rpc/delegate-utils.js";
17
+ function isHeartbeatResponse(payload) {
18
+ return (typeof payload === "object" &&
19
+ payload !== null &&
20
+ payload["type"] === "heartbeat");
21
+ }
22
+ async function isRPCConnectionHealthy(rpc, timeout = HEALTH_CHECK_TIMEOUT_MS) {
23
+ try {
24
+ const req = rpc.request(getNextCommandId());
25
+ req.send(JSON.stringify({ type: "heartbeat" }), "utf-8");
26
+ const response = await withTimeout(req.reply("utf-8"), timeout);
27
+ const payload = JSON.parse(response?.toString() || "{}");
28
+ return isHeartbeatResponse(payload);
29
+ }
30
+ catch (error) {
31
+ logger.debug("RPC health check failed", { error });
32
+ return false;
33
+ }
34
+ }
13
35
  /**
14
36
  * Register the swarm "connection" handler once (not per getRPC call).
15
37
  * This fixes the event listener leak where each getRPC() call added
@@ -36,11 +58,13 @@ function ensureConnectionHandler() {
36
58
  logger.debug(`Connection closed for peer: ${peerPubkey}`);
37
59
  activeRPCs.delete(peerPubkey);
38
60
  activeConnections.delete(peerPubkey);
61
+ clearPeerConnectionTracking(peerPubkey);
39
62
  });
40
63
  conn.on("error", (err) => {
41
64
  logger.error(`Connection error for peer ${peerPubkey}:`, err);
42
65
  activeRPCs.delete(peerPubkey);
43
66
  activeConnections.delete(peerPubkey);
67
+ clearPeerConnectionTracking(peerPubkey);
44
68
  });
45
69
  });
46
70
  }
@@ -60,16 +84,35 @@ async function closeConnection(publicKey) {
60
84
  });
61
85
  activeConnections.delete(publicKey);
62
86
  activeRPCs.delete(publicKey);
87
+ clearPeerConnectionTracking(publicKey);
63
88
  }
64
89
  }
65
90
  // Establish RPC connection to a peer if not already connected
66
- async function ensureRPCConnection(topic, publicKey, timeout) {
91
+ async function ensureRPCConnection(topic, publicKey, timeout, healthCheckTimeout) {
92
+ const healthCheckCap = healthCheckTimeout ?? HEALTH_CHECK_TIMEOUT_MS;
93
+ const operationStart = nowMs();
94
+ const getRemainingTimeout = () => {
95
+ if (timeout === undefined) {
96
+ return undefined;
97
+ }
98
+ return Math.max(timeout - (nowMs() - operationStart), 0);
99
+ };
67
100
  // Check if we already have an RPC instance for this peer
68
101
  const existingRpc = activeRPCs.get(publicKey);
69
102
  if (existingRpc) {
70
- return existingRpc;
103
+ const remainingTimeout = getRemainingTimeout();
104
+ const probeTimeout = remainingTimeout === undefined
105
+ ? healthCheckCap
106
+ : Math.min(remainingTimeout / 2, healthCheckCap);
107
+ const isHealthy = await isRPCConnectionHealthy(existingRpc, probeTimeout);
108
+ if (isHealthy) {
109
+ return existingRpc;
110
+ }
111
+ logger.info(`🧹 Cached RPC failed health check for peer ${publicKey}, reconnecting`);
112
+ cleanupStaleConnection(publicKey);
71
113
  }
72
114
  const swarm = getSwarm();
115
+ const connectionStart = nowMs();
73
116
  // Track the listener so we can clean it up on timeout
74
117
  let onConnection = () => { };
75
118
  try {
@@ -126,20 +169,17 @@ async function ensureRPCConnection(topic, publicKey, timeout) {
126
169
  logger.debug(`⏳ Peer not connected after flush, waiting for connection event...`);
127
170
  });
128
171
  });
129
- return await withTimeout(connectionPromise, timeout);
172
+ const rpc = await withTimeout(connectionPromise, getRemainingTimeout());
173
+ const connectionDuration = nowMs() - connectionStart;
174
+ cacheDelegationConnectionTime(publicKey, connectionDuration);
175
+ return rpc;
130
176
  }
131
177
  catch (error) {
132
178
  // Clean up the per-request connection listener
133
179
  swarm.removeListener("connection", onConnection);
134
180
  // Remove stale connection so next attempt creates a fresh one
135
181
  // instead of reusing a dead RPC
136
- logger.info(`🗑️ Removing stale connection for peer: ${publicKey} after failed RPC attempt`);
137
- activeRPCs.delete(publicKey);
138
- const conn = activeConnections.get(publicKey);
139
- if (conn) {
140
- conn.destroy();
141
- activeConnections.delete(publicKey);
142
- }
182
+ cleanupStaleConnection(publicKey);
143
183
  logger.error("Failed to establish RPC connection:", error);
144
184
  throw new DelegateConnectionFailedError(`RPC connection failed: ${error instanceof Error ? error.message : String(error)}`, error);
145
185
  }
@@ -153,7 +193,7 @@ export async function getRPC(topic, publicKey, options = {}) {
153
193
  if (options.forceNewConnection) {
154
194
  await closeConnection(publicKey);
155
195
  }
156
- return await ensureRPCConnection(topic, publicKey, options.timeout);
196
+ return await ensureRPCConnection(topic, publicKey, options.timeout, options.healthCheckTimeout);
157
197
  }
158
198
  /**
159
199
  * Remove a stale RPC connection for a peer.
@@ -168,4 +208,5 @@ export function cleanupStaleConnection(publicKey) {
168
208
  conn.destroy();
169
209
  activeConnections.delete(publicKey);
170
210
  }
211
+ clearPeerConnectionTracking(publicKey);
171
212
  }
@@ -1,3 +1,9 @@
1
1
  import { type LoadModelServerParams } from "../../../schemas/index";
2
- export declare function loadModel(params: LoadModelServerParams): Promise<void>;
2
+ import type { LoadTimingStats } from "../../../profiling/types";
3
+ export interface LoadModelResult {
4
+ timing?: LoadTimingStats;
5
+ }
6
+ export declare function loadModel(params: LoadModelServerParams, options?: {
7
+ collectTiming?: boolean;
8
+ }): Promise<LoadModelResult>;
3
9
  //# sourceMappingURL=load-model.d.ts.map
@@ -1,27 +1,32 @@
1
- import { loadModelServerParamsSchema, ModelType, normalizeModelType, } from "../../../schemas/index.js";
1
+ import { loadModelServerParamsSchema, normalizeModelType, } from "../../../schemas/index.js";
2
+ import { nowMs } from "../../../profiling/clock.js";
2
3
  import { isModelLoaded, registerModel, } from "../registry/model-registry.js";
3
4
  import { startLogBuffering, stopLogBufferingWithTimeout, } from "../registry/logging-stream-registry.js";
4
5
  import { detectShardedModel, generateShardFilenames, validateShardedModelCache, } from "../../utils/index.js";
5
- import { ModelLoadFailedError, PluginNotFoundError, ModelFileNotFoundError, ModelFileNotFoundInDirError, ModelFileLocateFailedError, } from "../../../utils/errors-server.js";
6
+ import { PluginNotFoundError, ModelFileNotFoundError, ModelFileNotFoundInDirError, ModelFileLocateFailedError, } from "../../../utils/errors-server.js";
6
7
  import { getPlugin } from "../../plugins/index.js";
7
8
  import { promises as fsPromises } from "bare-fs";
8
9
  import path from "bare-path";
9
10
  import { getServerLogger } from "../../../logging/index.js";
10
11
  const logger = getServerLogger();
11
- export async function loadModel(params) {
12
- const { modelId, modelPath, options, projectionModelPath, vadModelPath, detectorModelPath, modelName, } = loadModelServerParamsSchema.parse(params);
13
- const { modelConfig, modelType: rawModelType } = options;
12
+ export async function loadModel(params, options) {
13
+ const { modelId, modelPath, options: modelOptions, artifacts, modelName } = loadModelServerParamsSchema.parse(params);
14
+ const { modelConfig, modelType: rawModelType } = modelOptions;
14
15
  // Normalize modelType to canonical form (handles aliases and custom types)
15
16
  const modelType = normalizeModelType(rawModelType);
16
17
  // Check if model is already loaded
17
18
  if (isModelLoaded(modelId)) {
18
19
  logger.info(`${modelType} model ${modelId} is already loaded`);
19
- return;
20
+ return {};
20
21
  }
21
22
  // Detect if sharded model
22
23
  const modelFileName = path.basename(modelPath);
23
24
  const shardInfo = detectShardedModel(modelFileName);
24
25
  const isShardedModel = shardInfo.isSharded;
26
+ const plugin = getPlugin(modelType);
27
+ if (!plugin) {
28
+ throw new PluginNotFoundError(modelType);
29
+ }
25
30
  if (isShardedModel) {
26
31
  // For sharded models, validate all shards and tensors.txt exist
27
32
  const shardDir = path.dirname(modelPath);
@@ -31,9 +36,8 @@ export async function loadModel(params) {
31
36
  throw new ModelFileNotFoundError(`Missing shards or ${shardInfo.baseFilename}.tensors.txt. Expected ${numberedShards.length} shard files + tensors.txt in ${shardDir}`);
32
37
  }
33
38
  }
34
- else if (modelType !== ModelType.onnxTts) {
39
+ else if (!plugin.skipPrimaryModelPathValidation) {
35
40
  // For non-sharded models, validate single file exists
36
- // Skip for TTS - it uses multiple paths from modelConfig (resolved by plugin.resolveConfig)
37
41
  try {
38
42
  const modelDir = path.dirname(modelPath);
39
43
  const modelFile = path.basename(modelPath);
@@ -47,40 +51,35 @@ export async function loadModel(params) {
47
51
  throw new ModelFileLocateFailedError(modelType, modelPath, error);
48
52
  }
49
53
  }
50
- if (modelType === ModelType.onnxOcr && !detectorModelPath) {
51
- throw new ModelLoadFailedError("Detector model required for OCR. Use a hyperdrive source or provide detectorModelSrc");
52
- }
53
- const plugin = getPlugin(modelType);
54
- if (!plugin) {
55
- throw new PluginNotFoundError(modelType);
56
- }
57
- // Build artifacts map for plugin
58
- // Note: TTS paths are in modelConfig (resolved by plugin.resolveConfig), not artifacts
59
- const artifacts = {};
60
- if (projectionModelPath)
61
- artifacts["projectionModelPath"] = projectionModelPath;
62
- if (vadModelPath)
63
- artifacts["vadModelPath"] = vadModelPath;
64
- if (detectorModelPath)
65
- artifacts["detectorModelPath"] = detectorModelPath;
66
- const result = plugin.createModel({
67
- modelId,
68
- modelPath,
69
- modelConfig: modelConfig,
70
- modelName,
71
- artifacts: Object.keys(artifacts).length > 0 ? artifacts : undefined,
72
- });
73
54
  logger.info(`${modelType}: Loading model ${modelId}...`);
74
55
  startLogBuffering(modelId);
75
- await result.model.load(false);
76
- logger.info(`${modelType} model ${modelId} loaded`);
77
- stopLogBufferingWithTimeout(modelId);
78
- registerModel(modelId, {
79
- model: result.model,
80
- path: modelPath,
81
- config: modelConfig,
82
- modelType: modelType,
83
- name: modelName,
84
- loader: result.loader,
85
- });
56
+ try {
57
+ const initStart = options?.collectTiming ? nowMs() : 0;
58
+ const result = plugin.createModel({
59
+ modelId,
60
+ modelPath,
61
+ modelConfig: modelConfig,
62
+ modelName,
63
+ artifacts,
64
+ });
65
+ await result.model.load(false);
66
+ const modelInitializationTimeMs = options?.collectTiming
67
+ ? nowMs() - initStart
68
+ : undefined;
69
+ logger.info(`${modelType} model ${modelId} loaded`);
70
+ registerModel(modelId, {
71
+ model: result.model,
72
+ path: modelPath,
73
+ config: modelConfig,
74
+ modelType: modelType,
75
+ name: modelName,
76
+ loader: result.loader,
77
+ });
78
+ return modelInitializationTimeMs !== undefined
79
+ ? { timing: { modelInitializationTimeMs } }
80
+ : {};
81
+ }
82
+ finally {
83
+ stopLogBufferingWithTimeout(modelId);
84
+ }
86
85
  }
@@ -0,0 +1,3 @@
1
+ import { type TranscribeParams } from "../../../schemas/index";
2
+ export declare function transcribe(params: TranscribeParams): AsyncGenerator<string, void, void>;
3
+ //# sourceMappingURL=transcribe.d.ts.map
@@ -0,0 +1,75 @@
1
+ import { getModel, getModelConfig, getModelEntry, } from "../registry/model-registry.js";
2
+ import { ModelType, } from "../../../schemas/index.js";
3
+ import { createAudioStream } from "../utils/audio-input.js";
4
+ import { getServerLogger } from "../../../logging/index.js";
5
+ const logger = getServerLogger();
6
+ const SILENCE_MARKERS = {
7
+ [ModelType.whispercppTranscription]: "[BLANK_AUDIO]",
8
+ [ModelType.parakeetTranscription]: "[No speech detected]",
9
+ };
10
+ function getEngineModelType(modelId) {
11
+ const entry = getModelEntry(modelId);
12
+ return entry?.local?.modelType ?? "";
13
+ }
14
+ function getAudioFormat(modelId, engineType) {
15
+ if (engineType === ModelType.whispercppTranscription) {
16
+ const config = getModelConfig(modelId);
17
+ return config.audio_format || "s16le";
18
+ }
19
+ return "s16le";
20
+ }
21
+ async function applyPrompt(modelId, prompt, engineType) {
22
+ if (engineType !== ModelType.whispercppTranscription || !prompt) {
23
+ return null;
24
+ }
25
+ const model = getModel(modelId);
26
+ if (typeof model.reload !== "function")
27
+ return null;
28
+ const originalConfig = getModelConfig(modelId);
29
+ const updatedConfig = { ...originalConfig, initial_prompt: prompt };
30
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
31
+ const { contextParams: _, miscConfig, ...whisperParams } = updatedConfig;
32
+ await model.reload({
33
+ whisperConfig: whisperParams,
34
+ ...(miscConfig && { miscConfig }),
35
+ });
36
+ return originalConfig;
37
+ }
38
+ async function restorePrompt(modelId, originalConfig) {
39
+ const model = getModel(modelId);
40
+ if (typeof model.reload !== "function")
41
+ return;
42
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
43
+ const { contextParams: _, miscConfig, ...whisperParams } = originalConfig;
44
+ await model.reload({
45
+ whisperConfig: { ...whisperParams, initial_prompt: "" },
46
+ ...(miscConfig && { miscConfig }),
47
+ });
48
+ }
49
+ export async function* transcribe(params) {
50
+ const { modelId } = params;
51
+ const engineType = getEngineModelType(modelId);
52
+ const silenceMarker = SILENCE_MARKERS[engineType] ?? "";
53
+ const audioFormat = getAudioFormat(modelId, engineType);
54
+ const originalConfig = await applyPrompt(modelId, params.prompt, engineType);
55
+ try {
56
+ const model = getModel(modelId);
57
+ const audioStream = await createAudioStream(params.audioChunk, audioFormat);
58
+ const response = await model.run(audioStream);
59
+ for await (const output of response.iterate()) {
60
+ logger.debug("Streaming Transcription Update:", output);
61
+ const text = output
62
+ .filter((chunk) => !silenceMarker || !chunk.text.includes(silenceMarker))
63
+ .map((chunk) => chunk.text)
64
+ .join("");
65
+ if (text.trim()) {
66
+ yield text;
67
+ }
68
+ }
69
+ }
70
+ finally {
71
+ if (originalConfig) {
72
+ await restorePrompt(modelId, originalConfig);
73
+ }
74
+ }
75
+ }
@@ -1,3 +1,5 @@
1
1
  import { type TranslateParams, type TranslationStats } from "../../../schemas/index";
2
+ export declare function getLanguage(code: string | undefined): string;
3
+ export declare function isAfrican(code: string | undefined): boolean;
2
4
  export declare function translate(params: TranslateParams): AsyncGenerator<string, TranslationStats | undefined, unknown>;
3
5
  //# sourceMappingURL=translate.d.ts.map
@@ -1,12 +1,17 @@
1
1
  import { getModel } from "../registry/model-registry.js";
2
- import { translateServerParamsSchema, normalizeModelType, ModelType, } from "../../../schemas/index.js";
2
+ import { translateServerParamsSchema, normalizeModelType, ModelType, AFRICAN_LANGUAGES_MAP, } from "../../../schemas/index.js";
3
3
  import { getLangName } from "@qvac/langdetect-text";
4
- function getLanguage(code) {
4
+ export function getLanguage(code) {
5
5
  if (!code)
6
6
  return "";
7
+ if (AFRICAN_LANGUAGES_MAP.has(code))
8
+ return AFRICAN_LANGUAGES_MAP.get(code);
7
9
  const fullName = getLangName(code);
8
10
  return fullName ?? code.toUpperCase();
9
11
  }
12
+ export function isAfrican(code) {
13
+ return !!code && AFRICAN_LANGUAGES_MAP.has(code);
14
+ }
10
15
  export async function* translate(params) {
11
16
  const { modelId, text, modelType: inputModelType } = params;
12
17
  const canonicalModelType = normalizeModelType(inputModelType);
@@ -14,6 +19,7 @@ export async function* translate(params) {
14
19
  const from = isLlm ? params.from : undefined;
15
20
  const to = isLlm ? params.to : undefined;
16
21
  const context = isLlm ? params.context : undefined;
22
+ const afriquePrompt = isLlm && (isAfrican(from) || isAfrican(to));
17
23
  translateServerParamsSchema.parse(params);
18
24
  const model = getModel(modelId);
19
25
  const fromLanguage = getLanguage(from);
@@ -47,8 +53,10 @@ export async function* translate(params) {
47
53
  ? singleText
48
54
  : [
49
55
  {
50
- role: "system",
51
- content: `${context ? `${context}. ` : ""}Translate the following text from ${fromLanguage} into ${toLanguage}. Only output the translation, nothing else.\n\n${fromLanguage}: ${singleText}\n${toLanguage}:`,
56
+ role: afriquePrompt ? "user" : "system",
57
+ content: afriquePrompt
58
+ ? `Translate ${fromLanguage} to ${toLanguage}.\n${fromLanguage}: ${singleText}\n${toLanguage}:`
59
+ : `${context ? `${context}. ` : ""}Translate the following text from ${fromLanguage} into ${toLanguage}. Only output the translation, nothing else.\n\n${fromLanguage}: ${singleText}\n${toLanguage}:`,
52
60
  },
53
61
  ];
54
62
  const response = await model.run(input);
@@ -1,6 +1,7 @@
1
1
  export { llmPlugin } from "./llamacpp-completion/plugin";
2
2
  export { embeddingsPlugin } from "./llamacpp-embedding/plugin";
3
3
  export { whisperPlugin } from "./whispercpp-transcription/plugin";
4
+ export { parakeetPlugin } from "./parakeet-transcription/plugin";
4
5
  export { nmtPlugin } from "./nmtcpp-translation/plugin";
5
6
  export { ttsPlugin } from "./onnx-tts/plugin";
6
7
  export { ocrPlugin } from "./onnx-ocr/plugin";
@@ -1,6 +1,7 @@
1
1
  export { llmPlugin } from "./llamacpp-completion/plugin.js";
2
2
  export { embeddingsPlugin } from "./llamacpp-embedding/plugin.js";
3
3
  export { whisperPlugin } from "./whispercpp-transcription/plugin.js";
4
+ export { parakeetPlugin } from "./parakeet-transcription/plugin.js";
4
5
  export { nmtPlugin } from "./nmtcpp-translation/plugin.js";
5
6
  export { ttsPlugin } from "./onnx-tts/plugin.js";
6
7
  export { ocrPlugin } from "./onnx-ocr/plugin.js";
@@ -1,6 +1,7 @@
1
- import type { CompletionParams, CompletionStats, Tool, ToolCall, ToolCallEvent } from "../../../../../schemas/index";
1
+ import type { CompletionParams, CompletionStats, GenerationParams, Tool, ToolCall, ToolCallEvent } from "../../../../../schemas/index";
2
2
  export declare function completion(params: CompletionParams & {
3
3
  tools?: Tool[];
4
+ generationParams?: GenerationParams;
4
5
  }): AsyncGenerator<{
5
6
  token: string;
6
7
  toolCallEvent?: ToolCallEvent;
@@ -78,8 +78,10 @@ function prepareMessagesForCache(cachePathToUse, cacheExists, history) {
78
78
  ...transformedHistoryWithoutSystem,
79
79
  ];
80
80
  }
81
- async function* processModelResponse(model, messagesToSend, shouldSaveCache, tools) {
82
- const response = await model.run(messagesToSend);
81
+ async function* processModelResponse(model, messagesToSend, shouldSaveCache, tools, generationParams) {
82
+ const runFn = model.run.bind(model);
83
+ const runOptions = generationParams ? { generationParams } : undefined;
84
+ const response = await runFn(messagesToSend, runOptions);
83
85
  let accumulatedText = "";
84
86
  const emittedToolCallPositions = new Set();
85
87
  let toolCallsResult = [];
@@ -114,7 +116,7 @@ async function* processModelResponse(model, messagesToSend, shouldSaveCache, too
114
116
  return { stats, toolCalls: toolCallsResult };
115
117
  }
116
118
  export async function* completion(params) {
117
- const { history, modelId, kvCache, tools } = params;
119
+ const { history, modelId, kvCache, tools, generationParams } = params;
118
120
  const modelConfig = getModelConfig(modelId);
119
121
  const toolsEnabled = modelConfig.tools === true;
120
122
  let historyWithTools = history;
@@ -143,7 +145,7 @@ export async function* completion(params) {
143
145
  }
144
146
  const messagesToSend = prepareMessagesForCache(cachePathToUse, cacheExists, history);
145
147
  logMessagesToAddon(messagesToSend, "PROMPT_SEND");
146
- return yield* processModelResponse(model, messagesToSend, true, tools);
148
+ return yield* processModelResponse(model, messagesToSend, true, tools, generationParams);
147
149
  }
148
150
  else {
149
151
  // Auto-generate cache key based on conversation history
@@ -167,7 +169,7 @@ export async function* completion(params) {
167
169
  }
168
170
  const messagesToSend = prepareMessagesForCache(cachePathToUse, cacheExists, history);
169
171
  logMessagesToAddon(messagesToSend, "PROMPT_SEND");
170
- const result = yield* processModelResponse(model, messagesToSend, true, tools);
172
+ const result = yield* processModelResponse(model, messagesToSend, true, tools, generationParams);
171
173
  //If there was an existing cache, we rename it with new hash that includes the current message
172
174
  if (existingCache !== null &&
173
175
  existingCache.cachePath !== currentCacheInfo.cachePath) {
@@ -179,6 +181,6 @@ export async function* completion(params) {
179
181
  else {
180
182
  logCacheDisabled();
181
183
  logMessagesToAddon(transformedHistory, "NO_CACHE");
182
- return yield* processModelResponse(model, transformedHistory, false, tools);
184
+ return yield* processModelResponse(model, transformedHistory, false, tools, generationParams);
183
185
  }
184
186
  }
@@ -1,8 +1,103 @@
1
- import { type CreateModelParams, type PluginModelResult } from "../../../../schemas/index";
1
+ import { type CreateModelParams, type PluginModelResult, type ResolveContext, type LlmConfigInput } from "../../../../schemas/index";
2
2
  export declare const llmPlugin: {
3
3
  modelType: "llamacpp-completion";
4
4
  displayName: string;
5
- addonPackage: string;
5
+ addonPackage: "@qvac/llm-llamacpp";
6
+ loadConfigSchema: import("zod").ZodObject<{
7
+ ctx_size: import("zod").ZodOptional<import("zod").ZodNumber>;
8
+ temp: import("zod").ZodOptional<import("zod").ZodNumber>;
9
+ top_p: import("zod").ZodOptional<import("zod").ZodNumber>;
10
+ top_k: import("zod").ZodOptional<import("zod").ZodNumber>;
11
+ seed: import("zod").ZodOptional<import("zod").ZodNumber>;
12
+ gpu_layers: import("zod").ZodOptional<import("zod").ZodNumber>;
13
+ lora: import("zod").ZodOptional<import("zod").ZodString>;
14
+ device: import("zod").ZodOptional<import("zod").ZodString>;
15
+ predict: import("zod").ZodOptional<import("zod").ZodUnion<readonly [import("zod").ZodLiteral<-1>, import("zod").ZodLiteral<-2>, import("zod").ZodNumber]>>;
16
+ system_prompt: import("zod").ZodOptional<import("zod").ZodString>;
17
+ no_mmap: import("zod").ZodOptional<import("zod").ZodBoolean>;
18
+ verbosity: import("zod").ZodOptional<import("zod").ZodUnion<readonly [import("zod").ZodLiteral<0>, import("zod").ZodLiteral<1>, import("zod").ZodLiteral<2>, import("zod").ZodLiteral<3>]>>;
19
+ presence_penalty: import("zod").ZodOptional<import("zod").ZodNumber>;
20
+ frequency_penalty: import("zod").ZodOptional<import("zod").ZodNumber>;
21
+ repeat_penalty: import("zod").ZodOptional<import("zod").ZodNumber>;
22
+ stop_sequences: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString>>;
23
+ n_discarded: import("zod").ZodOptional<import("zod").ZodNumber>;
24
+ tools: import("zod").ZodOptional<import("zod").ZodBoolean>;
25
+ projectionModelSrc: import("zod").ZodOptional<import("zod").ZodUnion<readonly [import("zod").ZodString, import("zod").ZodObject<{
26
+ src: import("zod").ZodString;
27
+ name: import("zod").ZodOptional<import("zod").ZodString>;
28
+ modelId: import("zod").ZodOptional<import("zod").ZodString>;
29
+ registryPath: import("zod").ZodOptional<import("zod").ZodString>;
30
+ registrySource: import("zod").ZodOptional<import("zod").ZodString>;
31
+ blobCoreKey: import("zod").ZodOptional<import("zod").ZodString>;
32
+ blobIndex: import("zod").ZodOptional<import("zod").ZodNumber>;
33
+ engine: import("zod").ZodOptional<import("zod").ZodString>;
34
+ expectedSize: import("zod").ZodOptional<import("zod").ZodNumber>;
35
+ sha256Checksum: import("zod").ZodOptional<import("zod").ZodString>;
36
+ addon: import("zod").ZodOptional<import("zod").ZodUnion<readonly [import("zod").ZodEnum<{
37
+ "llamacpp-completion": "llamacpp-completion";
38
+ "whispercpp-transcription": "whispercpp-transcription";
39
+ "llamacpp-embedding": "llamacpp-embedding";
40
+ "nmtcpp-translation": "nmtcpp-translation";
41
+ "onnx-tts": "onnx-tts";
42
+ "parakeet-transcription": "parakeet-transcription";
43
+ "onnx-ocr": "onnx-ocr";
44
+ llm: "llm";
45
+ whisper: "whisper";
46
+ embeddings: "embeddings";
47
+ nmt: "nmt";
48
+ parakeet: "parakeet";
49
+ tts: "tts";
50
+ ocr: "ocr";
51
+ }>, import("zod").ZodLiteral<"vad">]>>;
52
+ }, import("zod/v4/core").$strip>]>>;
53
+ }, import("zod/v4/core").$strip>;
54
+ resolveConfig(cfg: LlmConfigInput, ctx: ResolveContext): Promise<{
55
+ config: {
56
+ ctx_size?: number | undefined;
57
+ temp?: number | undefined;
58
+ top_p?: number | undefined;
59
+ top_k?: number | undefined;
60
+ seed?: number | undefined;
61
+ gpu_layers?: number | undefined;
62
+ lora?: string | undefined;
63
+ device?: string | undefined;
64
+ predict?: number | undefined;
65
+ system_prompt?: string | undefined;
66
+ no_mmap?: boolean | undefined;
67
+ verbosity?: 0 | 3 | 2 | 1 | undefined;
68
+ presence_penalty?: number | undefined;
69
+ frequency_penalty?: number | undefined;
70
+ repeat_penalty?: number | undefined;
71
+ stop_sequences?: string[] | undefined;
72
+ n_discarded?: number | undefined;
73
+ tools?: boolean | undefined;
74
+ };
75
+ artifacts?: never;
76
+ } | {
77
+ config: {
78
+ ctx_size?: number | undefined;
79
+ temp?: number | undefined;
80
+ top_p?: number | undefined;
81
+ top_k?: number | undefined;
82
+ seed?: number | undefined;
83
+ gpu_layers?: number | undefined;
84
+ lora?: string | undefined;
85
+ device?: string | undefined;
86
+ predict?: number | undefined;
87
+ system_prompt?: string | undefined;
88
+ no_mmap?: boolean | undefined;
89
+ verbosity?: 0 | 3 | 2 | 1 | undefined;
90
+ presence_penalty?: number | undefined;
91
+ frequency_penalty?: number | undefined;
92
+ repeat_penalty?: number | undefined;
93
+ stop_sequences?: string[] | undefined;
94
+ n_discarded?: number | undefined;
95
+ tools?: boolean | undefined;
96
+ };
97
+ artifacts: {
98
+ projectionModelPath: string;
99
+ };
100
+ }>;
6
101
  createModel(params: CreateModelParams): PluginModelResult;
7
102
  handlers: {
8
103
  completionStream: import("../../../../schemas/index").PluginHandlerDefinition<import("zod").ZodObject<{
@@ -37,6 +132,16 @@ export declare const llmPlugin: {
37
132
  }, import("zod/v4/core").$strip>>>;
38
133
  stream: import("zod").ZodBoolean;
39
134
  kvCache: import("zod").ZodOptional<import("zod").ZodUnion<readonly [import("zod").ZodBoolean, import("zod").ZodString]>>;
135
+ generationParams: import("zod").ZodOptional<import("zod").ZodObject<{
136
+ temp: import("zod").ZodOptional<import("zod").ZodNumber>;
137
+ top_p: import("zod").ZodOptional<import("zod").ZodNumber>;
138
+ top_k: import("zod").ZodOptional<import("zod").ZodNumber>;
139
+ predict: import("zod").ZodOptional<import("zod").ZodNumber>;
140
+ seed: import("zod").ZodOptional<import("zod").ZodNumber>;
141
+ frequency_penalty: import("zod").ZodOptional<import("zod").ZodNumber>;
142
+ presence_penalty: import("zod").ZodOptional<import("zod").ZodNumber>;
143
+ repeat_penalty: import("zod").ZodOptional<import("zod").ZodNumber>;
144
+ }, import("zod/v4/core").$strict>>;
40
145
  type: import("zod").ZodLiteral<"completionStream">;
41
146
  }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
42
147
  type: import("zod").ZodLiteral<"completionStream">;
@@ -109,7 +214,7 @@ export declare const llmPlugin: {
109
214
  };
110
215
  logging: {
111
216
  module: import("@qvac/llm-llamacpp/addonLogging").AddonLogging;
112
- namespace: "llamacpp:llm";
217
+ namespace: "llamacpp-completion";
113
218
  };
114
219
  };
115
220
  //# sourceMappingURL=plugin.d.ts.map
@@ -1,7 +1,7 @@
1
1
  import LlmLlamacpp, {} from "@qvac/llm-llamacpp";
2
2
  import llmAddonLogging from "@qvac/llm-llamacpp/addonLogging.js";
3
- import { definePlugin, defineHandler, completionStreamRequestSchema, completionStreamResponseSchema, translateRequestSchema, translateResponseSchema, ModelType, } from "../../../../schemas/index.js";
4
- import { ADDON_NAMESPACES, createStreamLogger, registerAddonLogger, } from "../../../../logging/index.js";
3
+ import { definePlugin, defineHandler, completionStreamRequestSchema, completionStreamResponseSchema, translateRequestSchema, translateResponseSchema, ModelType, llmConfigBaseSchema, ADDON_LLM, } from "../../../../schemas/index.js";
4
+ import { createStreamLogger, registerAddonLogger } from "../../../../logging/index.js";
5
5
  import { parseModelPath } from "../../../utils/index.js";
6
6
  import FilesystemDL from "@qvac/dl-filesystem";
7
7
  import { asLoader } from "../../utils/loader-adapter.js";
@@ -26,8 +26,8 @@ function transformLlmConfig(llmConfig) {
26
26
  function createLlmModel(modelId, modelPath, llmConfig, projectionModelPath) {
27
27
  const { dirPath, basePath } = parseModelPath(modelPath);
28
28
  const loader = new FilesystemDL({ dirPath });
29
- const logger = createStreamLogger(modelId, ADDON_NAMESPACES.LLAMACPP_LLM);
30
- registerAddonLogger(modelId, ADDON_NAMESPACES.LLAMACPP_LLM, logger);
29
+ const logger = createStreamLogger(modelId, ModelType.llamacppCompletion);
30
+ registerAddonLogger(modelId, ModelType.llamacppCompletion, logger);
31
31
  const llmConfigStrings = transformLlmConfig(llmConfig);
32
32
  const args = {
33
33
  loader: asLoader(loader),
@@ -47,7 +47,19 @@ function createLlmModel(modelId, modelPath, llmConfig, projectionModelPath) {
47
47
  export const llmPlugin = definePlugin({
48
48
  modelType: ModelType.llamacppCompletion,
49
49
  displayName: "LLM (llama.cpp)",
50
- addonPackage: "@qvac/llm-llamacpp",
50
+ addonPackage: ADDON_LLM,
51
+ loadConfigSchema: llmConfigBaseSchema,
52
+ async resolveConfig(cfg, ctx) {
53
+ const { projectionModelSrc, ...llmConfig } = cfg;
54
+ if (!projectionModelSrc) {
55
+ return { config: llmConfig };
56
+ }
57
+ const projectionModelPath = await ctx.resolveModelPath(projectionModelSrc);
58
+ return {
59
+ config: llmConfig,
60
+ artifacts: { projectionModelPath },
61
+ };
62
+ },
51
63
  createModel(params) {
52
64
  const llmConfig = (params.modelConfig ?? {});
53
65
  const { model, loader } = createLlmModel(params.modelId, params.modelPath, llmConfig, params.artifacts?.["projectionModelPath"]);
@@ -69,6 +81,7 @@ export const llmPlugin = definePlugin({
69
81
  modelId: request.modelId,
70
82
  kvCache: request.kvCache,
71
83
  ...(request.tools && { tools: request.tools }),
84
+ ...(request.generationParams && { generationParams: request.generationParams }),
72
85
  });
73
86
  let stats;
74
87
  let toolCalls = [];
@@ -137,6 +150,6 @@ export const llmPlugin = definePlugin({
137
150
  },
138
151
  logging: {
139
152
  module: llmAddonLogging,
140
- namespace: ADDON_NAMESPACES.LLAMACPP_LLM,
153
+ namespace: ModelType.llamacppCompletion,
141
154
  },
142
155
  });