@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
@@ -1,32 +1,44 @@
1
- import { modelInputToSrcSchema } from "../../../schemas/index.js";
2
- import { registerModel } from "../../bare/registry/model-registry.js";
3
- import { send, stream } from "../delegate-transport.js";
4
- import { getRPC, cleanupStaleConnection, } from "../../bare/delegate-rpc-client.js";
1
+ import { DELEGATION_BREAKDOWN_KEY, OPERATION_EVENT_KEY, modelInputToSrcSchema } from "../../../schemas/index.js";
2
+ import { registerModel, isModelLoaded, unregisterModel } from "../../bare/registry/model-registry.js";
3
+ import { send, stream, } from "../delegate-transport.js";
4
+ import { getRPC } from "../../bare/delegate-rpc-client.js";
5
5
  import { handleLoadModel } from "./load-model/index.js";
6
6
  import { ModelLoadFailedError, DelegateNoFinalResponseError, } from "../../../utils/errors-server.js";
7
7
  import { getServerLogger } from "../../../logging/index.js";
8
8
  const logger = getServerLogger();
9
- export async function handleLoadModelDelegated(request, progressCallback) {
9
+ export async function handleLoadModelDelegated(request, options) {
10
+ const { progressCallback, profilingMeta } = options ?? {};
10
11
  if (!request.delegate) {
11
12
  throw new ModelLoadFailedError("Delegate information is required for delegated load model");
12
13
  }
13
14
  const { delegate } = request;
14
- const { topic, providerPublicKey, timeout, fallbackToLocal, forceNewConnection, } = delegate;
15
+ const { topic, providerPublicKey, timeout, healthCheckTimeout, fallbackToLocal, forceNewConnection, } = delegate;
15
16
  try {
16
17
  logger.info(`📤 Sending delegated loadModel request to provider: ${providerPublicKey}${timeout ? `, timeout: ${timeout}ms` : ""}${forceNewConnection ? " (forcing new connection)" : ""}`);
17
18
  // Create RPC instance for this HyperSwarm peer
18
19
  const rpc = await getRPC(topic, providerPublicKey, {
19
20
  timeout,
21
+ healthCheckTimeout,
20
22
  forceNewConnection,
21
23
  });
22
24
  // Strip out the delegate field to avoid infinite delegation
23
25
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
24
26
  const { delegate: _, ...providerRequest } = request;
25
27
  let finalResponse;
28
+ let delegationBreakdown;
29
+ let operationEvent;
30
+ // Build delegate options with profiling metadata
31
+ const delegateOpts = { peerKey: providerPublicKey };
32
+ if (profilingMeta) {
33
+ delegateOpts.profilingMeta = profilingMeta;
34
+ }
35
+ if (timeout) {
36
+ delegateOpts.timeout = timeout;
37
+ }
26
38
  if (request.withProgress) {
27
39
  // Use streaming for progress updates
28
40
  logger.debug("📊 Using streaming mode for loadModel with progress");
29
- const responseStream = stream(providerRequest, rpc, timeout ? { timeout } : {});
41
+ const responseStream = stream(providerRequest, rpc, delegateOpts);
30
42
  for await (const response of responseStream) {
31
43
  if (response.type === "modelProgress") {
32
44
  // Forward progress updates to the client
@@ -36,6 +48,7 @@ export async function handleLoadModelDelegated(request, progressCallback) {
36
48
  }
37
49
  else if (response.type === "loadModel") {
38
50
  finalResponse = response;
51
+ operationEvent = response[OPERATION_EVENT_KEY];
39
52
  break;
40
53
  }
41
54
  }
@@ -46,7 +59,11 @@ export async function handleLoadModelDelegated(request, progressCallback) {
46
59
  else {
47
60
  // Use simple send for non-progress requests
48
61
  logger.debug("📤 Using simple send mode for loadModel");
49
- finalResponse = (await send(providerRequest, rpc, timeout ? { timeout } : {}));
62
+ const providerResponse = await send(providerRequest, rpc, delegateOpts);
63
+ finalResponse = providerResponse;
64
+ const typedResponse = providerResponse;
65
+ delegationBreakdown = typedResponse[DELEGATION_BREAKDOWN_KEY];
66
+ operationEvent = typedResponse[OPERATION_EVENT_KEY];
50
67
  }
51
68
  if (!finalResponse || !finalResponse.success) {
52
69
  logger.error("Provider failed to load model:", finalResponse?.error);
@@ -66,18 +83,31 @@ export async function handleLoadModelDelegated(request, progressCallback) {
66
83
  if (timeout !== undefined) {
67
84
  delegateOptions.timeout = timeout;
68
85
  }
86
+ if (healthCheckTimeout !== undefined) {
87
+ delegateOptions.healthCheckTimeout = healthCheckTimeout;
88
+ }
89
+ if (isModelLoaded(modelId)) {
90
+ logger.info(`Delegated model ${modelId} is already registered, replacing with new provider: ${providerPublicKey}`);
91
+ unregisterModel(modelId);
92
+ }
69
93
  registerModel(modelId, delegateOptions);
70
94
  logger.info(`✅ Delegated model registered: ${modelId} -> provider: ${providerPublicKey}`);
71
- return {
95
+ const result = {
72
96
  type: "loadModel",
73
97
  success: true,
74
98
  modelId,
75
99
  };
100
+ if (delegationBreakdown) {
101
+ result[DELEGATION_BREAKDOWN_KEY] =
102
+ delegationBreakdown;
103
+ }
104
+ if (operationEvent) {
105
+ result[OPERATION_EVENT_KEY] = operationEvent;
106
+ }
107
+ return result;
76
108
  }
77
109
  catch (error) {
78
110
  logger.error("Error in delegated load model:", error);
79
- // Clean up stale RPC so next attempt creates a fresh connection
80
- cleanupStaleConnection(providerPublicKey);
81
111
  if (fallbackToLocal) {
82
112
  logger.info("🔄 Fallback to local model loading enabled, attempting local load...");
83
113
  try {
@@ -1,5 +1,6 @@
1
1
  import { getModelEntry } from "../../bare/registry/model-registry.js";
2
2
  import { getPlugin } from "../../plugins/index.js";
3
+ import { profileReplyHandler, profileStreamHandler, } from "../profiling/index.js";
3
4
  import { ModelNotFoundError, ModelIsDelegatedError, PluginNotFoundError, PluginHandlerNotFoundError, PluginHandlerTypeMismatchError, } from "../../../utils/errors-server.js";
4
5
  /**
5
6
  * Resolves the plugin handler and returns both the result and streaming flag.
@@ -33,11 +34,13 @@ function resolvePluginHandler(modelId, handlerName, request) {
33
34
  * @throws PluginHandlerTypeMismatchError if the handler is streaming
34
35
  */
35
36
  export async function dispatchPluginReply(modelId, handlerName, request) {
36
- const { result, streaming } = resolvePluginHandler(modelId, handlerName, request);
37
- if (streaming) {
38
- throw new PluginHandlerTypeMismatchError(handlerName, "reply", "streaming");
39
- }
40
- return result;
37
+ return profileReplyHandler({ op: handlerName, request }, async () => {
38
+ const { result, streaming } = resolvePluginHandler(modelId, handlerName, request);
39
+ if (streaming) {
40
+ throw new PluginHandlerTypeMismatchError(handlerName, "reply", "streaming");
41
+ }
42
+ return result;
43
+ });
41
44
  }
42
45
  /**
43
46
  * Dispatches a request to a plugin handler and returns an AsyncGenerator.
@@ -46,9 +49,11 @@ export async function dispatchPluginReply(modelId, handlerName, request) {
46
49
  * @throws PluginHandlerTypeMismatchError if the handler is not streaming
47
50
  */
48
51
  export async function* dispatchPluginStream(modelId, handlerName, request) {
49
- const { result, streaming } = resolvePluginHandler(modelId, handlerName, request);
50
- if (!streaming) {
51
- throw new PluginHandlerTypeMismatchError(handlerName, "streaming", "reply");
52
- }
53
- yield* result;
52
+ yield* profileStreamHandler({ op: handlerName, request }, async function* () {
53
+ const { result, streaming } = resolvePluginHandler(modelId, handlerName, request);
54
+ if (!streaming) {
55
+ throw new PluginHandlerTypeMismatchError(handlerName, "streaming", "reply");
56
+ }
57
+ yield* result;
58
+ });
54
59
  }
@@ -1,5 +1,6 @@
1
1
  import { getModelEntry } from "../../bare/registry/model-registry.js";
2
2
  import { getPlugin, getPluginHandler } from "../../plugins/index.js";
3
+ import { profileReplyHandler, profileStreamHandler, } from "../profiling/index.js";
3
4
  import { PluginNotFoundError, PluginHandlerNotFoundError, PluginHandlerTypeMismatchError, PluginRequestValidationFailedError, PluginResponseValidationFailedError, ModelIsDelegatedError, ModelNotFoundError, } from "../../../utils/errors-server.js";
4
5
  import { getServerLogger } from "../../../logging/index.js";
5
6
  const logger = getServerLogger();
@@ -24,64 +25,68 @@ function resolvePluginHandler(modelId, handlerName) {
24
25
  return { modelType, plugin, handlerDef };
25
26
  }
26
27
  export async function handlePluginInvoke(request) {
27
- const { modelId, handler: handlerName, params } = request;
28
- logger.debug(`[pluginInvoke] modelId=${modelId} handler=${handlerName}`);
29
- const { handlerDef } = resolvePluginHandler(modelId, handlerName);
30
- if (handlerDef.streaming) {
31
- throw new PluginHandlerTypeMismatchError(handlerName, "reply", "streaming");
32
- }
33
- const parseResult = handlerDef.requestSchema.safeParse(params);
34
- if (!parseResult.success) {
35
- const details = parseResult.error.issues
36
- .map((i) => `${String(i.path.join("."))}: ${i.message}`)
37
- .join(", ");
38
- throw new PluginRequestValidationFailedError(handlerName, details);
39
- }
40
- const result = await handlerDef.handler(parseResult.data);
41
- const responseParseResult = handlerDef.responseSchema.safeParse(result);
42
- if (!responseParseResult.success) {
43
- const details = responseParseResult.error.issues
44
- .map((i) => `${String(i.path.join("."))}: ${i.message}`)
45
- .join(", ");
46
- throw new PluginResponseValidationFailedError(handlerName, details);
47
- }
48
- return {
49
- type: "pluginInvoke",
50
- result: responseParseResult.data,
51
- };
52
- }
53
- export async function* handlePluginInvokeStream(request) {
54
- const { modelId, handler: handlerName, params } = request;
55
- logger.debug(`[pluginInvokeStream] modelId=${modelId} handler=${handlerName}`);
56
- const { handlerDef } = resolvePluginHandler(modelId, handlerName);
57
- if (!handlerDef.streaming) {
58
- throw new PluginHandlerTypeMismatchError(handlerName, "streaming", "reply");
59
- }
60
- const parseResult = handlerDef.requestSchema.safeParse(params);
61
- if (!parseResult.success) {
62
- const details = parseResult.error.issues
63
- .map((i) => `${String(i.path.join("."))}: ${i.message}`)
64
- .join(", ");
65
- throw new PluginRequestValidationFailedError(handlerName, details);
66
- }
67
- const generator = handlerDef.handler(parseResult.data);
68
- for await (const chunk of generator) {
69
- const responseParseResult = handlerDef.responseSchema.safeParse(chunk);
28
+ return profileReplyHandler({ op: "pluginInvoke", request }, async () => {
29
+ const { modelId, handler: handlerName, params } = request;
30
+ logger.debug(`[pluginInvoke] modelId=${modelId} handler=${handlerName}`);
31
+ const { handlerDef } = resolvePluginHandler(modelId, handlerName);
32
+ if (handlerDef.streaming) {
33
+ throw new PluginHandlerTypeMismatchError(handlerName, "reply", "streaming");
34
+ }
35
+ const parseResult = handlerDef.requestSchema.safeParse(params);
36
+ if (!parseResult.success) {
37
+ const details = parseResult.error.issues
38
+ .map((i) => `${String(i.path.join("."))}: ${i.message}`)
39
+ .join(", ");
40
+ throw new PluginRequestValidationFailedError(handlerName, details);
41
+ }
42
+ const result = await handlerDef.handler(parseResult.data);
43
+ const responseParseResult = handlerDef.responseSchema.safeParse(result);
70
44
  if (!responseParseResult.success) {
71
45
  const details = responseParseResult.error.issues
72
46
  .map((i) => `${String(i.path.join("."))}: ${i.message}`)
73
47
  .join(", ");
74
48
  throw new PluginResponseValidationFailedError(handlerName, details);
75
49
  }
50
+ return {
51
+ type: "pluginInvoke",
52
+ result: responseParseResult.data,
53
+ };
54
+ });
55
+ }
56
+ export async function* handlePluginInvokeStream(request) {
57
+ yield* profileStreamHandler({ op: "pluginInvokeStream", request }, async function* () {
58
+ const { modelId, handler: handlerName, params } = request;
59
+ logger.debug(`[pluginInvokeStream] modelId=${modelId} handler=${handlerName}`);
60
+ const { handlerDef } = resolvePluginHandler(modelId, handlerName);
61
+ if (!handlerDef.streaming) {
62
+ throw new PluginHandlerTypeMismatchError(handlerName, "streaming", "reply");
63
+ }
64
+ const parseResult = handlerDef.requestSchema.safeParse(params);
65
+ if (!parseResult.success) {
66
+ const details = parseResult.error.issues
67
+ .map((i) => `${String(i.path.join("."))}: ${i.message}`)
68
+ .join(", ");
69
+ throw new PluginRequestValidationFailedError(handlerName, details);
70
+ }
71
+ const generator = handlerDef.handler(parseResult.data);
72
+ for await (const chunk of generator) {
73
+ const responseParseResult = handlerDef.responseSchema.safeParse(chunk);
74
+ if (!responseParseResult.success) {
75
+ const details = responseParseResult.error.issues
76
+ .map((i) => `${String(i.path.join("."))}: ${i.message}`)
77
+ .join(", ");
78
+ throw new PluginResponseValidationFailedError(handlerName, details);
79
+ }
80
+ yield {
81
+ type: "pluginInvokeStream",
82
+ result: responseParseResult.data,
83
+ done: false,
84
+ };
85
+ }
76
86
  yield {
77
87
  type: "pluginInvokeStream",
78
- result: responseParseResult.data,
79
- done: false,
88
+ result: null,
89
+ done: true,
80
90
  };
81
- }
82
- yield {
83
- type: "pluginInvokeStream",
84
- result: null,
85
- done: true,
86
- };
91
+ });
87
92
  }
@@ -1,4 +1,25 @@
1
1
  import { chunk, ingest, reindex, saveEmbeddings, search, deleteEmbeddings, listWorkspaces, closeWorkspace, deleteWorkspace, DEFAULT_WORKSPACE, registerRagOperation, unregisterRagOperation, } from "../../bare/rag-hyperdb/index.js";
2
+ import { profileReplyHandler, registerOperationMetrics, } from "../profiling/index.js";
3
+ registerOperationMetrics({
4
+ op: "rag",
5
+ kind: "handler",
6
+ getTags: (req) => {
7
+ const tags = {};
8
+ if (req.operation)
9
+ tags["operation"] = req.operation;
10
+ if (req.workspace)
11
+ tags["workspace"] = req.workspace;
12
+ return tags;
13
+ },
14
+ fromResult: (res) => {
15
+ const gauges = {};
16
+ if (res.processed !== undefined)
17
+ gauges["processed"] = res.processed.length;
18
+ if (res.results !== undefined)
19
+ gauges["resultsCount"] = res.results.length;
20
+ return Object.keys(gauges).length > 0 ? gauges : undefined;
21
+ },
22
+ });
2
23
  function createHandlerOptions(operation, workspace, onProgress) {
3
24
  const signal = registerRagOperation(workspace, operation);
4
25
  const options = { signal };
@@ -22,6 +43,9 @@ function omitOnProgress(obj) {
22
43
  return rest;
23
44
  }
24
45
  export async function handleRag(request, onProgress) {
46
+ return profileReplyHandler({ op: "rag", request }, async () => handleRagInternal(request, onProgress));
47
+ }
48
+ async function handleRagInternal(request, onProgress) {
25
49
  switch (request.operation) {
26
50
  case "chunk": {
27
51
  const chunks = await chunk(request);
@@ -0,0 +1,3 @@
1
+ import type { UnloadModelRequest, UnloadModelResponse } from "../../../schemas/index";
2
+ export declare function handleUnloadModelDelegated(request: UnloadModelRequest): Promise<UnloadModelResponse>;
3
+ //# sourceMappingURL=unload-model-delegated.d.ts.map
@@ -0,0 +1,32 @@
1
+ import { getModelEntry, unregisterModel } from "../../bare/registry/model-registry.js";
2
+ import { getRPC } from "../../bare/delegate-rpc-client.js";
3
+ import { send } from "../delegate-transport.js";
4
+ import { hasActiveProviders } from "../../bare/hyperswarm.js";
5
+ import { getRegistryStats } from "../../bare/registry/model-registry.js";
6
+ import { ModelIsDelegatedError } from "../../../utils/errors-server.js";
7
+ import { getServerLogger } from "../../../logging/index.js";
8
+ const logger = getServerLogger();
9
+ export async function handleUnloadModelDelegated(request) {
10
+ const entry = getModelEntry(request.modelId);
11
+ if (!entry?.isDelegated || !entry.delegated) {
12
+ throw new ModelIsDelegatedError(request.modelId);
13
+ }
14
+ const { topic, providerPublicKey, timeout, healthCheckTimeout } = entry.delegated;
15
+ unregisterModel(request.modelId);
16
+ try {
17
+ logger.info(`Sending delegated unload for model ${request.modelId} to provider: ${providerPublicKey}`);
18
+ const rpc = await getRPC(topic, providerPublicKey, { timeout, healthCheckTimeout });
19
+ await send({ type: "unloadModel", modelId: request.modelId, clearStorage: false }, rpc, { timeout, peerKey: providerPublicKey });
20
+ logger.info(`Delegated model ${request.modelId} unloaded on provider`);
21
+ }
22
+ catch (error) {
23
+ logger.error(`Failed to unload delegated model ${request.modelId} on provider:`, error);
24
+ }
25
+ const stats = getRegistryStats();
26
+ return {
27
+ type: "unloadModel",
28
+ success: true,
29
+ hasActiveModels: stats.totalModels > 0,
30
+ hasActiveProviders: hasActiveProviders(),
31
+ };
32
+ }
@@ -0,0 +1,18 @@
1
+ import { type ProfilingRequestMeta, type DelegationBreakdown, type OperationEvent } from "../../../schemas/index";
2
+ export interface ServerProfilingContext {
3
+ meta: ProfilingRequestMeta;
4
+ requestStart: number;
5
+ jsonParseMs?: number;
6
+ zodValidationMs?: number;
7
+ handlerExecutionMs?: number;
8
+ responseZodValidationMs?: number;
9
+ responseStringifyMs?: number;
10
+ }
11
+ export declare function createProfilingContext(meta: ProfilingRequestMeta): ServerProfilingContext;
12
+ export interface ProfilingInjectionOptions {
13
+ ctx?: ServerProfilingContext;
14
+ delegation?: DelegationBreakdown;
15
+ operation?: OperationEvent;
16
+ }
17
+ export declare function injectProfilingIntoString(jsonString: string, options: ProfilingInjectionOptions): string;
18
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1,38 @@
1
+ import { PROFILING_KEY, } from "../../../schemas/index.js";
2
+ import { nowMs } from "../../../profiling/index.js";
3
+ export function createProfilingContext(meta) {
4
+ return { meta, requestStart: nowMs() };
5
+ }
6
+ function buildServerBreakdown(ctx) {
7
+ return {
8
+ requestJsonParseMs: ctx.jsonParseMs,
9
+ requestZodValidationMs: ctx.zodValidationMs,
10
+ handlerExecutionMs: ctx.handlerExecutionMs,
11
+ responseZodValidationMs: ctx.responseZodValidationMs,
12
+ responseStringifyMs: ctx.responseStringifyMs,
13
+ totalServerMs: nowMs() - ctx.requestStart,
14
+ };
15
+ }
16
+ export function injectProfilingIntoString(jsonString, options) {
17
+ const { ctx, delegation, operation } = options;
18
+ const includeServer = ctx?.meta.includeServer ?? false;
19
+ const hasContent = includeServer || !!delegation || !!operation;
20
+ if (!hasContent || !jsonString.endsWith("}")) {
21
+ return jsonString;
22
+ }
23
+ const id = ctx?.meta.id ?? delegation?.profileId ?? operation?.profileId ?? "";
24
+ const profilingMeta = { id };
25
+ if (includeServer && ctx) {
26
+ profilingMeta["server"] = buildServerBreakdown(ctx);
27
+ }
28
+ if (delegation) {
29
+ const { profileId: _unused, ...delegationWithoutId } = delegation;
30
+ void _unused;
31
+ profilingMeta["delegation"] = delegationWithoutId;
32
+ }
33
+ if (operation) {
34
+ profilingMeta["operation"] = operation;
35
+ }
36
+ return (jsonString.slice(0, -1) +
37
+ `,"${PROFILING_KEY}":${JSON.stringify(profilingMeta)}}`);
38
+ }
@@ -0,0 +1,32 @@
1
+ import { type BaseTimings } from "../../../profiling/index";
2
+ import type { ProfilingRequestMeta, ProfilingResponseMeta, DelegationBreakdown } from "../../../schemas/index";
3
+ export interface DelegatedHandlerOptions {
4
+ profilingMeta?: ProfilingRequestMeta;
5
+ }
6
+ interface BaseDelegationTimings extends BaseTimings {
7
+ requestStringifyMs?: number;
8
+ sendStart?: number;
9
+ }
10
+ export interface DelegationTimings extends BaseDelegationTimings {
11
+ firstResponseAt?: number;
12
+ responseJsonParseMs?: number;
13
+ }
14
+ export interface DelegationStreamTimings extends BaseDelegationTimings {
15
+ firstChunkAt?: number;
16
+ lastChunkAt?: number;
17
+ chunkCount: number;
18
+ }
19
+ export declare function shouldProfileDelegation(op: string, incomingMeta?: ProfilingRequestMeta): boolean;
20
+ export declare function createDelegationTimings(profileId: string, requestType: string): DelegationTimings;
21
+ export declare function createDelegationStreamTimings(profileId: string, requestType: string): DelegationStreamTimings;
22
+ export declare function cacheDelegationConnectionTime(peerKey: string, durationMs: number): void;
23
+ export declare function flushServerConnectionEvent(peerKey: string): void;
24
+ export declare function consumeBreakdownConnectionTime(peerKey: string): number | undefined;
25
+ export declare function buildDelegationBreakdown(timings: DelegationTimings, connectionMs?: number): DelegationBreakdown;
26
+ export declare function buildDelegationStreamBreakdown(timings: DelegationStreamTimings): DelegationBreakdown;
27
+ export declare function recordDelegationEvents(timings: DelegationTimings, serverMeta?: ProfilingResponseMeta, connectionMs?: number): DelegationBreakdown;
28
+ export declare function recordDelegationStreamEvents(timings: DelegationStreamTimings, serverMeta?: ProfilingResponseMeta): void;
29
+ export declare function clearPeerConnectionTracking(peerKey: string): void;
30
+ export declare function resetDelegationConnectionTracking(): void;
31
+ export {};
32
+ //# sourceMappingURL=delegation-profiler.d.ts.map
@@ -0,0 +1,154 @@
1
+ import { nowMs, record, shouldProfile, recordPhase, recordServerBreakdownPhases, } from "../../../profiling/index.js";
2
+ /**
3
+ * Per-peer connection tracking for delegation.
4
+ * Separate tracking for server-side event recording vs breakdown injection.
5
+ *
6
+ * Flow:
7
+ * 1. Connection happens → cacheDelegationConnectionTime stores ms
8
+ * 2. First profiled call (stream or unary) → flushServerConnectionEvent records server event
9
+ * 3. First unary call → consumeBreakdownConnectionTime returns ms for breakdown injection
10
+ */
11
+ const pendingConnectionTimes = new Map();
12
+ const serverConnectionRecorded = new Map();
13
+ const breakdownConnectionMs = new Map();
14
+ const breakdownConnectionInjected = new Map();
15
+ export function shouldProfileDelegation(op, incomingMeta) {
16
+ if (incomingMeta?.enabled === false) {
17
+ return false;
18
+ }
19
+ if (incomingMeta?.enabled === true) {
20
+ return true;
21
+ }
22
+ return shouldProfile(op);
23
+ }
24
+ export function createDelegationTimings(profileId, requestType) {
25
+ return { profileId, requestType, requestStart: nowMs() };
26
+ }
27
+ export function createDelegationStreamTimings(profileId, requestType) {
28
+ return { profileId, requestType, requestStart: nowMs(), chunkCount: 0 };
29
+ }
30
+ export function cacheDelegationConnectionTime(peerKey, durationMs) {
31
+ if (serverConnectionRecorded.get(peerKey))
32
+ return;
33
+ if (pendingConnectionTimes.has(peerKey))
34
+ return;
35
+ pendingConnectionTimes.set(peerKey, durationMs);
36
+ }
37
+ export function flushServerConnectionEvent(peerKey) {
38
+ if (serverConnectionRecorded.get(peerKey))
39
+ return;
40
+ const ms = pendingConnectionTimes.get(peerKey);
41
+ if (ms === undefined)
42
+ return;
43
+ pendingConnectionTimes.delete(peerKey);
44
+ serverConnectionRecorded.set(peerKey, true);
45
+ if (!breakdownConnectionInjected.get(peerKey)) {
46
+ breakdownConnectionMs.set(peerKey, ms);
47
+ }
48
+ record({
49
+ ts: nowMs(),
50
+ op: "delegation",
51
+ kind: "delegation",
52
+ phase: "connection",
53
+ ms,
54
+ tags: { peer: peerKey.slice(0, 16) },
55
+ });
56
+ }
57
+ export function consumeBreakdownConnectionTime(peerKey) {
58
+ if (breakdownConnectionInjected.get(peerKey))
59
+ return undefined;
60
+ const ms = breakdownConnectionMs.get(peerKey);
61
+ if (ms === undefined)
62
+ return undefined;
63
+ breakdownConnectionMs.delete(peerKey);
64
+ breakdownConnectionInjected.set(peerKey, true);
65
+ return ms;
66
+ }
67
+ export function buildDelegationBreakdown(timings, connectionMs) {
68
+ const now = nowMs();
69
+ const breakdown = {
70
+ profileId: timings.profileId,
71
+ };
72
+ if (connectionMs !== undefined) {
73
+ breakdown.connectionMs = connectionMs;
74
+ }
75
+ if (timings.requestStringifyMs !== undefined) {
76
+ breakdown.requestStringifyMs = timings.requestStringifyMs;
77
+ }
78
+ if (timings.sendStart !== undefined &&
79
+ timings.firstResponseAt !== undefined) {
80
+ breakdown.serverWaitMs = timings.firstResponseAt - timings.sendStart;
81
+ }
82
+ if (timings.responseJsonParseMs !== undefined) {
83
+ breakdown.responseJsonParseMs = timings.responseJsonParseMs;
84
+ }
85
+ breakdown.totalDelegationMs = now - timings.requestStart;
86
+ return breakdown;
87
+ }
88
+ export function buildDelegationStreamBreakdown(timings) {
89
+ const now = nowMs();
90
+ const breakdown = {
91
+ profileId: timings.profileId,
92
+ };
93
+ if (timings.requestStringifyMs !== undefined) {
94
+ breakdown.requestStringifyMs = timings.requestStringifyMs;
95
+ }
96
+ if (timings.sendStart !== undefined && timings.firstChunkAt !== undefined) {
97
+ breakdown.serverWaitMs = timings.firstChunkAt - timings.sendStart;
98
+ }
99
+ breakdown.totalDelegationMs = now - timings.requestStart;
100
+ return breakdown;
101
+ }
102
+ export function recordDelegationEvents(timings, serverMeta, connectionMs) {
103
+ const now = nowMs();
104
+ const base = {
105
+ ts: now,
106
+ op: timings.requestType,
107
+ kind: "delegation",
108
+ profileId: timings.profileId,
109
+ };
110
+ const breakdown = buildDelegationBreakdown(timings, connectionMs);
111
+ recordPhase(base, "request.stringify", breakdown.requestStringifyMs);
112
+ recordPhase(base, "serverWait", breakdown.serverWaitMs);
113
+ recordPhase(base, "response.jsonParse", breakdown.responseJsonParseMs);
114
+ recordPhase(base, "totalDelegationTime", breakdown.totalDelegationMs);
115
+ if (serverMeta?.server) {
116
+ recordServerBreakdownPhases(base, serverMeta.server, "delegated");
117
+ }
118
+ return breakdown;
119
+ }
120
+ export function recordDelegationStreamEvents(timings, serverMeta) {
121
+ const now = nowMs();
122
+ const totalTime = now - timings.requestStart;
123
+ const base = {
124
+ ts: now,
125
+ op: timings.requestType,
126
+ kind: "delegation",
127
+ profileId: timings.profileId,
128
+ };
129
+ recordPhase(base, "request.stringify", timings.requestStringifyMs);
130
+ if (timings.sendStart !== undefined && timings.firstChunkAt !== undefined) {
131
+ recordPhase(base, "ttfb", timings.firstChunkAt - timings.sendStart);
132
+ }
133
+ if (timings.firstChunkAt !== undefined && timings.lastChunkAt !== undefined) {
134
+ recordPhase(base, "streamDuration", timings.lastChunkAt - timings.firstChunkAt);
135
+ }
136
+ recordPhase(base, "totalDelegationTime", totalTime, {
137
+ count: timings.chunkCount,
138
+ });
139
+ if (serverMeta?.server) {
140
+ recordServerBreakdownPhases(base, serverMeta.server, "delegated");
141
+ }
142
+ }
143
+ export function clearPeerConnectionTracking(peerKey) {
144
+ pendingConnectionTimes.delete(peerKey);
145
+ serverConnectionRecorded.delete(peerKey);
146
+ breakdownConnectionMs.delete(peerKey);
147
+ breakdownConnectionInjected.delete(peerKey);
148
+ }
149
+ export function resetDelegationConnectionTracking() {
150
+ pendingConnectionTimes.clear();
151
+ serverConnectionRecorded.clear();
152
+ breakdownConnectionMs.clear();
153
+ breakdownConnectionInjected.clear();
154
+ }
@@ -0,0 +1,5 @@
1
+ export { createServerProfiler, type ServerProfiler } from "./profiler";
2
+ export { profileReplyHandler, profileStreamHandler, } from "./operation-wrappers";
3
+ export { registerOperationMetrics, buildOperationEvent, type OperationMetricsConfig, } from "./operation-metrics";
4
+ export { shouldProfileDelegation, createDelegationTimings, createDelegationStreamTimings, recordDelegationEvents, recordDelegationStreamEvents, cacheDelegationConnectionTime, flushServerConnectionEvent, consumeBreakdownConnectionTime, clearPeerConnectionTracking, resetDelegationConnectionTracking, type DelegationTimings, type DelegationStreamTimings, type DelegatedHandlerOptions, } from "./delegation-profiler";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,4 @@
1
+ export { createServerProfiler } from "./profiler.js";
2
+ export { profileReplyHandler, profileStreamHandler, } from "./operation-wrappers.js";
3
+ export { registerOperationMetrics, buildOperationEvent, } from "./operation-metrics.js";
4
+ export { shouldProfileDelegation, createDelegationTimings, createDelegationStreamTimings, recordDelegationEvents, recordDelegationStreamEvents, cacheDelegationConnectionTime, flushServerConnectionEvent, consumeBreakdownConnectionTime, clearPeerConnectionTracking, resetDelegationConnectionTracking, } from "./delegation-profiler.js";
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Declarative extraction of operation-level metrics from request/response data.
3
+ * Used by operation wrappers to capture handler-specific profiling events.
4
+ */
5
+ import type { ProfilingEvent, ProfilingEventKind } from "../../../profiling/types";
6
+ import type { DownloadStats } from "../handlers/load-model/types";
7
+ export type MetricExtractor<T> = (data: T) => Record<string, number> | undefined;
8
+ export type TagExtractor<T> = (data: T) => Record<string, string> | undefined;
9
+ export interface OperationMetricsConfig<TRequest = unknown, TResponse = unknown> {
10
+ op: string;
11
+ kind: ProfilingEventKind;
12
+ fromRequest?: MetricExtractor<TRequest>;
13
+ fromFinalChunk?: MetricExtractor<TResponse>;
14
+ fromResult?: MetricExtractor<TResponse>;
15
+ getTags?: (request: TRequest) => Record<string, string>;
16
+ getTagsFromResult?: TagExtractor<TResponse>;
17
+ }
18
+ export interface DownloadAssetProfilingMeta {
19
+ sourceType?: string;
20
+ downloadStats?: DownloadStats;
21
+ totalDownloadTimeMs?: number;
22
+ }
23
+ export declare function registerOperationMetrics<TRequest, TResponse>(config: OperationMetricsConfig<TRequest, TResponse>): void;
24
+ export declare function buildOperationEvent(op: string, profileId: string, ts: number, executionMs: number, request?: unknown, finalResponse?: unknown, ttfb?: number): ProfilingEvent | undefined;
25
+ //# sourceMappingURL=operation-metrics.d.ts.map