@qvac/sdk 0.7.1 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE +57 -331
- package/README.md +2 -2
- package/bare-imports.json +9 -0
- package/dist/client/api/completion-stream.d.ts +2 -1
- package/dist/client/api/completion-stream.js +2 -1
- package/dist/client/api/download-asset.d.ts +3 -2
- package/dist/client/api/download-asset.js +4 -3
- package/dist/client/api/embed.d.ts +5 -2
- package/dist/client/api/embed.js +2 -2
- package/dist/client/api/get-model-info.d.ts +1 -1
- package/dist/client/api/invoke-plugin.d.ts +3 -2
- package/dist/client/api/invoke-plugin.js +4 -4
- package/dist/client/api/load-model.d.ts +12 -10
- package/dist/client/api/load-model.js +3 -3
- package/dist/client/api/rag.d.ts +10 -10
- package/dist/client/api/rag.js +21 -21
- package/dist/client/api/text-to-speech.d.ts +2 -2
- package/dist/client/api/text-to-speech.js +3 -3
- package/dist/client/api/transcribe.d.ts +5 -3
- package/dist/client/api/transcribe.js +6 -4
- package/dist/client/api/translate.d.ts +2 -2
- package/dist/client/api/translate.js +3 -3
- package/dist/client/rpc/node-rpc-client.d.ts +2 -7
- package/dist/client/rpc/node-rpc-client.js +2 -39
- package/dist/client/rpc/profiling/index.d.ts +2 -0
- package/dist/client/rpc/profiling/index.js +1 -0
- package/dist/client/rpc/profiling/profiler.d.ts +27 -0
- package/dist/client/rpc/profiling/profiler.js +139 -0
- package/dist/client/rpc/rpc-client.d.ts +2 -2
- package/dist/client/rpc/rpc-client.js +174 -12
- package/dist/examples/delegated-inference/consumer-profiled.d.ts +2 -0
- package/dist/examples/delegated-inference/consumer-profiled.js +67 -0
- package/dist/examples/llamacpp-multimodal.js +1 -1
- package/dist/examples/parallel-download.js +45 -13
- package/dist/examples/profiling/basic.d.ts +2 -0
- package/dist/examples/profiling/basic.js +71 -0
- package/dist/examples/profiling/per-call.d.ts +2 -0
- package/dist/examples/profiling/per-call.js +30 -0
- package/dist/examples/transcription/parakeet-ctc-filesystem.d.ts +2 -0
- package/dist/examples/transcription/parakeet-ctc-filesystem.js +40 -0
- package/dist/examples/transcription/parakeet-microphone-record.d.ts +2 -0
- package/dist/examples/transcription/parakeet-microphone-record.js +95 -0
- package/dist/examples/transcription/parakeet-sortformer.d.ts +2 -0
- package/dist/examples/transcription/parakeet-sortformer.js +115 -0
- package/dist/examples/transcription/parakeet-tdt-filesystem.d.ts +2 -0
- package/dist/examples/transcription/parakeet-tdt-filesystem.js +44 -0
- package/dist/examples/translation/translation-bergamot-pivot.d.ts +2 -0
- package/dist/examples/translation/translation-bergamot-pivot.js +73 -0
- package/dist/examples/translation/translation-llm-afriquegemma.d.ts +2 -0
- package/dist/examples/translation/translation-llm-afriquegemma.js +39 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2 -0
- package/dist/logging/index.d.ts +1 -1
- package/dist/logging/index.js +1 -1
- package/dist/logging/namespaces.d.ts +3 -9
- package/dist/logging/namespaces.js +2 -8
- package/dist/logging/registry.js +15 -1
- package/dist/models/registry/models.d.ts +1606 -245
- package/dist/models/registry/models.js +2127 -721
- package/dist/models/update-models/codegen.js +2 -2
- package/dist/models/update-models/history.d.ts +11 -0
- package/dist/models/update-models/history.js +24 -5
- package/dist/models/update-models/index.js +17 -16
- package/dist/models/update-models/naming.js +56 -0
- package/dist/profiling/aggregator.d.ts +15 -0
- package/dist/profiling/aggregator.js +100 -0
- package/dist/profiling/clock.d.ts +12 -0
- package/dist/profiling/clock.js +51 -0
- package/dist/profiling/controller.d.ts +33 -0
- package/dist/profiling/controller.js +123 -0
- package/dist/profiling/envelope.d.ts +10 -0
- package/dist/profiling/envelope.js +36 -0
- package/dist/profiling/events.d.ts +20 -0
- package/dist/profiling/events.js +37 -0
- package/dist/profiling/exporters.d.ts +10 -0
- package/dist/profiling/exporters.js +236 -0
- package/dist/profiling/index.d.ts +36 -0
- package/dist/profiling/index.js +31 -0
- package/dist/profiling/ring-buffer.d.ts +19 -0
- package/dist/profiling/ring-buffer.js +83 -0
- package/dist/profiling/types.d.ts +47 -0
- package/dist/profiling/types.js +1 -0
- package/dist/schemas/common.d.ts +1888 -133
- package/dist/schemas/common.js +2 -0
- package/dist/schemas/completion-stream.d.ts +31 -0
- package/dist/schemas/completion-stream.js +13 -0
- package/dist/schemas/download-asset.d.ts +14 -3
- package/dist/schemas/download-asset.js +3 -1
- package/dist/schemas/engine-addon-map.js +9 -6
- package/dist/schemas/get-model-info.d.ts +2 -0
- package/dist/schemas/get-model-info.js +1 -0
- package/dist/schemas/index.d.ts +2 -1
- package/dist/schemas/index.js +2 -1
- package/dist/schemas/llamacpp-config.d.ts +140 -14
- package/dist/schemas/llamacpp-config.js +11 -7
- package/dist/schemas/load-model.d.ts +9649 -2515
- package/dist/schemas/load-model.js +142 -182
- package/dist/schemas/model-src-utils.d.ts +10 -2
- package/dist/schemas/model-types.d.ts +19 -1
- package/dist/schemas/model-types.js +11 -0
- package/dist/schemas/ocr.d.ts +37 -0
- package/dist/schemas/ocr.js +5 -0
- package/dist/schemas/plugin.d.ts +51 -5
- package/dist/schemas/plugin.js +26 -0
- package/dist/schemas/profiling.d.ts +105 -0
- package/dist/schemas/profiling.js +66 -0
- package/dist/schemas/registry.d.ts +18 -0
- package/dist/schemas/registry.js +2 -0
- package/dist/schemas/reload-config.d.ts +126 -6
- package/dist/schemas/reload-config.js +1 -1
- package/dist/schemas/sdk-config.d.ts +2280 -24
- package/dist/schemas/sdk-config.js +6 -1
- package/dist/schemas/sdk-errors-client.d.ts +1 -0
- package/dist/schemas/sdk-errors-client.js +7 -0
- package/dist/schemas/sdk-errors-server.d.ts +3 -0
- package/dist/schemas/sdk-errors-server.js +15 -0
- package/dist/schemas/text-to-speech.d.ts +90 -68
- package/dist/schemas/text-to-speech.js +16 -33
- package/dist/schemas/transcription-config.d.ts +383 -0
- package/dist/schemas/{whispercpp-config.js → transcription-config.js} +29 -1
- package/dist/schemas/translation-config.d.ts +463 -8
- package/dist/schemas/translation-config.js +35 -2
- package/dist/server/bare/delegate-rpc-client.js +11 -1
- package/dist/server/bare/ops/load-model.d.ts +7 -1
- package/dist/server/bare/ops/load-model.js +41 -42
- package/dist/server/bare/ops/transcribe.d.ts +3 -0
- package/dist/server/bare/ops/transcribe.js +75 -0
- package/dist/server/bare/ops/translate.d.ts +2 -0
- package/dist/server/bare/ops/translate.js +12 -4
- package/dist/server/bare/plugins/index.d.ts +1 -0
- package/dist/server/bare/plugins/index.js +1 -0
- package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stream.d.ts +2 -1
- package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stream.js +8 -6
- package/dist/server/bare/plugins/llamacpp-completion/plugin.d.ts +108 -3
- package/dist/server/bare/plugins/llamacpp-completion/plugin.js +19 -6
- package/dist/server/bare/plugins/llamacpp-embedding/plugin.d.ts +32 -2
- package/dist/server/bare/plugins/llamacpp-embedding/plugin.js +31 -17
- package/dist/server/bare/plugins/nmtcpp-translation/plugin.d.ts +325 -3
- package/dist/server/bare/plugins/nmtcpp-translation/plugin.js +117 -10
- package/dist/server/bare/plugins/onnx-ocr/plugin.d.ts +50 -2
- package/dist/server/bare/plugins/onnx-ocr/plugin.js +46 -5
- package/dist/server/bare/plugins/onnx-tts/plugin.d.ts +351 -4
- package/dist/server/bare/plugins/onnx-tts/plugin.js +81 -61
- package/dist/server/bare/plugins/parakeet-transcription/plugin.d.ts +317 -0
- package/dist/server/bare/plugins/parakeet-transcription/plugin.js +154 -0
- package/dist/server/bare/plugins/whispercpp-transcription/plugin.d.ts +209 -3
- package/dist/server/bare/plugins/whispercpp-transcription/plugin.js +21 -9
- package/dist/server/bare/rag-hyperdb/rag-workspace-manager.js +2 -2
- package/dist/server/bare/registry/model-config-utils.js +3 -1
- package/dist/server/bare/utils/audio-input.d.ts +10 -0
- package/dist/server/bare/utils/audio-input.js +33 -0
- package/dist/server/error-handlers.d.ts +3 -2
- package/dist/server/error-handlers.js +11 -8
- package/dist/server/plugins/registry.js +5 -1
- package/dist/server/rpc/delegate-transport.d.ts +11 -3
- package/dist/server/rpc/delegate-transport.js +158 -3
- package/dist/server/rpc/handle-request.js +43 -4
- package/dist/server/rpc/handler-registry.js +7 -1
- package/dist/server/rpc/handler-utils.d.ts +5 -4
- package/dist/server/rpc/handler-utils.js +72 -31
- package/dist/server/rpc/handlers/completion-stream-delegated.d.ts +3 -1
- package/dist/server/rpc/handlers/completion-stream-delegated.js +11 -2
- package/dist/server/rpc/handlers/download-asset.js +55 -3
- package/dist/server/rpc/handlers/load-model/download-stats.d.ts +6 -0
- package/dist/server/rpc/handlers/load-model/download-stats.js +87 -0
- package/dist/server/rpc/handlers/load-model/handler.js +108 -123
- package/dist/server/rpc/handlers/load-model/http.d.ts +2 -1
- package/dist/server/rpc/handlers/load-model/http.js +21 -5
- package/dist/server/rpc/handlers/load-model/hyperdrive.d.ts +2 -1
- package/dist/server/rpc/handlers/load-model/hyperdrive.js +19 -14
- package/dist/server/rpc/handlers/load-model/registry.d.ts +2 -1
- package/dist/server/rpc/handlers/load-model/registry.js +123 -130
- package/dist/server/rpc/handlers/load-model/resolve.d.ts +2 -0
- package/dist/server/rpc/handlers/load-model/resolve.js +55 -22
- package/dist/server/rpc/handlers/load-model/types.d.ts +29 -0
- package/dist/server/rpc/handlers/load-model/types.js +1 -0
- package/dist/server/rpc/handlers/load-model-delegated.d.ts +5 -1
- package/dist/server/rpc/handlers/load-model-delegated.js +35 -7
- package/dist/server/rpc/handlers/plugin-dispatch.js +15 -10
- package/dist/server/rpc/handlers/plugin-invoke.js +56 -51
- package/dist/server/rpc/handlers/rag.js +24 -0
- package/dist/server/rpc/handlers/unload-model-delegated.d.ts +3 -0
- package/dist/server/rpc/handlers/unload-model-delegated.js +32 -0
- package/dist/server/rpc/profiling/context.d.ts +18 -0
- package/dist/server/rpc/profiling/context.js +38 -0
- package/dist/server/rpc/profiling/delegation-profiler.d.ts +32 -0
- package/dist/server/rpc/profiling/delegation-profiler.js +154 -0
- package/dist/server/rpc/profiling/index.d.ts +5 -0
- package/dist/server/rpc/profiling/index.js +4 -0
- package/dist/server/rpc/profiling/operation-metrics.d.ts +25 -0
- package/dist/server/rpc/profiling/operation-metrics.js +199 -0
- package/dist/server/rpc/profiling/operation-wrappers.d.ts +18 -0
- package/dist/server/rpc/profiling/operation-wrappers.js +124 -0
- package/dist/server/rpc/profiling/profiler.d.ts +13 -0
- package/dist/server/rpc/profiling/profiler.js +97 -0
- package/dist/server/utils/cache.d.ts +2 -1
- package/dist/server/utils/cache.js +5 -1
- package/dist/server/utils/checksum.d.ts +2 -0
- package/dist/server/utils/checksum.js +7 -0
- package/dist/server/utils/formatting.d.ts +6 -0
- package/dist/server/utils/formatting.js +35 -0
- package/dist/server/worker.js +2 -1
- package/dist/utils/errors-client.d.ts +3 -0
- package/dist/utils/errors-client.js +6 -0
- package/dist/utils/errors-server.d.ts +9 -0
- package/dist/utils/errors-server.js +15 -0
- package/dist/utils/global-singleton.d.ts +2 -0
- package/dist/utils/global-singleton.js +10 -0
- package/package.json +13 -16
- package/dist/schemas/whispercpp-config.d.ts +0 -70
- package/dist/server/bare/plugins/whispercpp-transcription/ops/transcribe-stream.d.ts +0 -3
- package/dist/server/bare/plugins/whispercpp-transcription/ops/transcribe-stream.js +0 -81
- /package/dist/examples/{whispercpp-filesystem.d.ts → transcription/whispercpp-filesystem.d.ts} +0 -0
- /package/dist/examples/{whispercpp-filesystem.js → transcription/whispercpp-filesystem.js} +0 -0
- /package/dist/examples/{whispercpp-microphone-record.d.ts → transcription/whispercpp-microphone-record.d.ts} +0 -0
- /package/dist/examples/{whispercpp-microphone-record.js → transcription/whispercpp-microphone-record.js} +0 -0
- /package/dist/examples/{whispercpp-prompt.d.ts → transcription/whispercpp-prompt.d.ts} +0 -0
- /package/dist/examples/{whispercpp-prompt.js → transcription/whispercpp-prompt.js} +0 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { nowMs, record, recordPhase, recordServerBreakdownPhases, recordDelegationBreakdownPhases, } from "../../../profiling/index.js";
|
|
2
|
+
import { getGlobalSingleton } from "../../../utils/global-singleton.js";
|
|
3
|
+
const CONNECTION_TRACKING_STATE_KEY = Symbol.for("@qvac/sdk:rpc-connection-tracking-state");
|
|
4
|
+
function getConnectionTrackingState() {
|
|
5
|
+
return getGlobalSingleton(CONNECTION_TRACKING_STATE_KEY, () => {
|
|
6
|
+
return {
|
|
7
|
+
connectionTimeRecorded: false,
|
|
8
|
+
pendingConnectionTimeMs: undefined,
|
|
9
|
+
};
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
function recordRequestPhases(base, timings) {
|
|
13
|
+
recordPhase(base, "request.zodValidation", timings.requestZodValidationMs);
|
|
14
|
+
recordPhase(base, "request.stringify", timings.requestStringifyMs);
|
|
15
|
+
if (timings.requestZodValidationMs !== undefined &&
|
|
16
|
+
timings.requestStringifyMs !== undefined) {
|
|
17
|
+
recordPhase(base, "request.totalSerialization", timings.requestZodValidationMs + timings.requestStringifyMs);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function createBaseTimings(profileId, requestType) {
|
|
21
|
+
return { profileId, requestType, requestStart: nowMs() };
|
|
22
|
+
}
|
|
23
|
+
export function createClientTimings(profileId, requestType) {
|
|
24
|
+
return createBaseTimings(profileId, requestType);
|
|
25
|
+
}
|
|
26
|
+
export function createClientStreamTimings(profileId, requestType) {
|
|
27
|
+
return { ...createBaseTimings(profileId, requestType), chunkCount: 0 };
|
|
28
|
+
}
|
|
29
|
+
export function cacheConnectionTime(durationMs) {
|
|
30
|
+
const state = getConnectionTrackingState();
|
|
31
|
+
if (state.connectionTimeRecorded)
|
|
32
|
+
return;
|
|
33
|
+
if (state.pendingConnectionTimeMs !== undefined)
|
|
34
|
+
return;
|
|
35
|
+
state.pendingConnectionTimeMs = durationMs;
|
|
36
|
+
}
|
|
37
|
+
export function flushConnectionTime() {
|
|
38
|
+
const state = getConnectionTrackingState();
|
|
39
|
+
if (state.connectionTimeRecorded)
|
|
40
|
+
return;
|
|
41
|
+
if (state.pendingConnectionTimeMs === undefined)
|
|
42
|
+
return;
|
|
43
|
+
const durationMs = state.pendingConnectionTimeMs;
|
|
44
|
+
state.pendingConnectionTimeMs = undefined;
|
|
45
|
+
state.connectionTimeRecorded = true;
|
|
46
|
+
record({
|
|
47
|
+
ts: nowMs(),
|
|
48
|
+
op: "rpc",
|
|
49
|
+
kind: "rpc",
|
|
50
|
+
phase: "connection",
|
|
51
|
+
ms: durationMs,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
export function recordClientEvents(timings, serverMeta) {
|
|
55
|
+
const now = nowMs();
|
|
56
|
+
const totalClientTime = now - timings.requestStart;
|
|
57
|
+
const base = {
|
|
58
|
+
ts: now,
|
|
59
|
+
op: timings.requestType,
|
|
60
|
+
kind: "rpc",
|
|
61
|
+
profileId: timings.profileId,
|
|
62
|
+
};
|
|
63
|
+
recordRequestPhases(base, timings);
|
|
64
|
+
// For unary requests, this measures send → full response received
|
|
65
|
+
if (timings.sendStart !== undefined &&
|
|
66
|
+
timings.firstResponseAt !== undefined) {
|
|
67
|
+
recordPhase(base, "serverWait", timings.firstResponseAt - timings.sendStart);
|
|
68
|
+
}
|
|
69
|
+
recordPhase(base, "response.jsonParse", timings.responseJsonParseMs);
|
|
70
|
+
recordPhase(base, "response.zodValidation", timings.responseZodValidationMs);
|
|
71
|
+
if (timings.responseJsonParseMs !== undefined &&
|
|
72
|
+
timings.responseZodValidationMs !== undefined) {
|
|
73
|
+
recordPhase(base, "response.totalParsing", timings.responseJsonParseMs + timings.responseZodValidationMs);
|
|
74
|
+
}
|
|
75
|
+
recordPhase(base, "totalClientTime", totalClientTime);
|
|
76
|
+
if (serverMeta?.server) {
|
|
77
|
+
recordServerBreakdownPhases(base, serverMeta.server, "server");
|
|
78
|
+
if (serverMeta.server.totalServerMs !== undefined) {
|
|
79
|
+
recordPhase(base, "clientOverhead", Math.max(0, totalClientTime - serverMeta.server.totalServerMs));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (serverMeta?.delegation) {
|
|
83
|
+
recordDelegationBreakdownPhases(base, serverMeta.delegation);
|
|
84
|
+
}
|
|
85
|
+
if (serverMeta?.operation) {
|
|
86
|
+
recordOperationEvent(serverMeta.operation);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function recordOperationEvent(op) {
|
|
90
|
+
const event = {
|
|
91
|
+
ts: nowMs(),
|
|
92
|
+
op: op.op,
|
|
93
|
+
kind: op.kind,
|
|
94
|
+
ms: op.ms,
|
|
95
|
+
};
|
|
96
|
+
if (op.profileId !== undefined)
|
|
97
|
+
event.profileId = op.profileId;
|
|
98
|
+
if (op.gauges !== undefined)
|
|
99
|
+
event.gauges = op.gauges;
|
|
100
|
+
if (op.tags !== undefined)
|
|
101
|
+
event.tags = op.tags;
|
|
102
|
+
if (op.count !== undefined)
|
|
103
|
+
event.count = op.count;
|
|
104
|
+
record(event);
|
|
105
|
+
}
|
|
106
|
+
export function recordClientStreamEvents(timings, serverMeta) {
|
|
107
|
+
const now = nowMs();
|
|
108
|
+
const totalClientTime = now - timings.requestStart;
|
|
109
|
+
const base = {
|
|
110
|
+
ts: now,
|
|
111
|
+
op: timings.requestType,
|
|
112
|
+
kind: "rpc",
|
|
113
|
+
profileId: timings.profileId,
|
|
114
|
+
};
|
|
115
|
+
recordRequestPhases(base, timings);
|
|
116
|
+
if (timings.sendStart !== undefined && timings.firstChunkAt !== undefined) {
|
|
117
|
+
recordPhase(base, "ttfb", timings.firstChunkAt - timings.sendStart);
|
|
118
|
+
}
|
|
119
|
+
if (timings.firstChunkAt !== undefined && timings.lastChunkAt !== undefined) {
|
|
120
|
+
recordPhase(base, "streamDuration", timings.lastChunkAt - timings.firstChunkAt);
|
|
121
|
+
}
|
|
122
|
+
recordPhase(base, "totalClientTime", totalClientTime, {
|
|
123
|
+
count: timings.chunkCount,
|
|
124
|
+
});
|
|
125
|
+
if (serverMeta?.server) {
|
|
126
|
+
recordServerBreakdownPhases(base, serverMeta.server, "server");
|
|
127
|
+
}
|
|
128
|
+
if (serverMeta?.delegation) {
|
|
129
|
+
recordDelegationBreakdownPhases(base, serverMeta.delegation);
|
|
130
|
+
}
|
|
131
|
+
if (serverMeta?.operation) {
|
|
132
|
+
recordOperationEvent(serverMeta.operation);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
export function resetConnectionTracking() {
|
|
136
|
+
const state = getConnectionTrackingState();
|
|
137
|
+
state.connectionTimeRecorded = false;
|
|
138
|
+
state.pendingConnectionTimeMs = undefined;
|
|
139
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type RPC from "bare-rpc";
|
|
2
2
|
import { type Request, type Response, type RPCOptions } from "../../schemas/index";
|
|
3
|
-
export declare function send<T extends Request>(request: T,
|
|
4
|
-
export declare function stream<T extends Request>(request: T,
|
|
3
|
+
export declare function send<T extends Request>(request: T, options?: RPCOptions, rpc?: RPC): Promise<Response>;
|
|
4
|
+
export declare function stream<T extends Request>(request: T, options?: RPCOptions, rpc?: RPC): AsyncGenerator<Response>;
|
|
5
5
|
export declare function close(): Promise<void>;
|
|
6
6
|
//# sourceMappingURL=rpc-client.d.ts.map
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import { requestSchema, responseSchema, } from "../../schemas/index.js";
|
|
1
|
+
import { requestSchema, responseSchema, PROFILING_TRAILER_KEY, } from "../../schemas/index.js";
|
|
2
2
|
import { RPCError } from "./rpc-error.js";
|
|
3
3
|
import { withTimeout, withTimeoutStream } from "../../utils/withTimeout.js";
|
|
4
4
|
import { getClientLogger, summarizeRequest } from "../../logging/index.js";
|
|
5
5
|
import { getRPC, close as closeRPC } from "#rpc";
|
|
6
|
+
import { nowMs, shouldProfile, shouldIncludeServerBreakdown, generateId as createProfileId, createProfilingMeta, createProfilingDisabledMeta, injectProfilingMetaIntoObject, extractProfilingMeta, stripProfilingMeta, recordFailure, } from "../../profiling/index.js";
|
|
7
|
+
import { createClientTimings, createClientStreamTimings, recordClientEvents, recordClientStreamEvents, cacheConnectionTime, flushConnectionTime, resetConnectionTracking, } from "./profiling/index.js";
|
|
6
8
|
const logger = getClientLogger();
|
|
7
9
|
let rpcInstance = null;
|
|
8
10
|
let commandCounter = 0;
|
|
11
|
+
let firstConnectionPending = true;
|
|
9
12
|
function getNextCommandId() {
|
|
10
13
|
commandCounter = (commandCounter + 1) % Number.MAX_SAFE_INTEGER;
|
|
11
14
|
return commandCounter;
|
|
@@ -17,16 +20,43 @@ function checkAndThrowError(response) {
|
|
|
17
20
|
}
|
|
18
21
|
async function getRPCInstance() {
|
|
19
22
|
if (rpcInstance)
|
|
20
|
-
return rpcInstance;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
return { rpc: await rpcInstance };
|
|
24
|
+
const connectionStart = firstConnectionPending ? nowMs() : null;
|
|
25
|
+
rpcInstance = getRPC();
|
|
26
|
+
const rpc = await rpcInstance;
|
|
27
|
+
if (connectionStart !== null && firstConnectionPending) {
|
|
28
|
+
firstConnectionPending = false;
|
|
29
|
+
return { rpc, connectionMs: nowMs() - connectionStart };
|
|
30
|
+
}
|
|
31
|
+
return { rpc };
|
|
32
|
+
}
|
|
33
|
+
async function prepareRPCContext(requestType, perCallProfiling, rpc) {
|
|
34
|
+
const rpcResult = rpc ? { rpc } : await getRPCInstance();
|
|
35
|
+
const profilingEnabled = shouldProfile(requestType, perCallProfiling);
|
|
36
|
+
const signalDisable = perCallProfiling?.enabled === false;
|
|
37
|
+
if (rpcResult.connectionMs !== undefined) {
|
|
38
|
+
cacheConnectionTime(rpcResult.connectionMs);
|
|
39
|
+
}
|
|
40
|
+
if (profilingEnabled) {
|
|
41
|
+
flushConnectionTime();
|
|
42
|
+
}
|
|
43
|
+
return { rpc: rpcResult.rpc, profilingEnabled, signalDisable };
|
|
44
|
+
}
|
|
45
|
+
export async function send(request, options, rpc) {
|
|
46
|
+
const ctx = await prepareRPCContext(request.type, options?.profiling, rpc);
|
|
47
|
+
if (!ctx.profilingEnabled) {
|
|
48
|
+
return sendBase(request, ctx.rpc, options, ctx.signalDisable);
|
|
49
|
+
}
|
|
50
|
+
return sendProfiled(request, ctx.rpc, options);
|
|
23
51
|
}
|
|
24
|
-
|
|
52
|
+
async function sendBase(request, rpc, options, signalDisable = false) {
|
|
25
53
|
const parsedRequest = requestSchema.parse(request);
|
|
26
|
-
const
|
|
27
|
-
const req = rpcInstance.request(getNextCommandId());
|
|
54
|
+
const req = rpc.request(getNextCommandId());
|
|
28
55
|
logger.debug("RPC Client sending:", summarizeRequest(request));
|
|
29
|
-
const
|
|
56
|
+
const payloadObj = signalDisable
|
|
57
|
+
? injectProfilingMetaIntoObject(parsedRequest, createProfilingDisabledMeta())
|
|
58
|
+
: parsedRequest;
|
|
59
|
+
const payload = JSON.stringify(payloadObj);
|
|
30
60
|
req.send(payload, "utf-8");
|
|
31
61
|
const response = await withTimeout(req.reply("utf-8"), options?.timeout);
|
|
32
62
|
const resPayload = responseSchema.parse(JSON.parse(response?.toString() || "{}"));
|
|
@@ -34,12 +64,69 @@ export async function send(request, rpc, options) {
|
|
|
34
64
|
checkAndThrowError(resPayload);
|
|
35
65
|
return resPayload;
|
|
36
66
|
}
|
|
37
|
-
|
|
67
|
+
async function sendProfiled(request, rpc, options) {
|
|
68
|
+
const requestType = request.type;
|
|
69
|
+
const profileId = createProfileId();
|
|
70
|
+
const includeServer = shouldIncludeServerBreakdown(options?.profiling);
|
|
71
|
+
const timings = createClientTimings(profileId, requestType);
|
|
72
|
+
try {
|
|
73
|
+
const zodStart = nowMs();
|
|
74
|
+
const parsedRequest = requestSchema.parse(request);
|
|
75
|
+
timings.requestZodValidationMs = nowMs() - zodStart;
|
|
76
|
+
const req = rpc.request(getNextCommandId());
|
|
77
|
+
logger.debug("RPC Client sending:", summarizeRequest(request));
|
|
78
|
+
const profilingMeta = createProfilingMeta(profileId, includeServer);
|
|
79
|
+
const requestWithMeta = injectProfilingMetaIntoObject(parsedRequest, profilingMeta);
|
|
80
|
+
const stringifyStart = nowMs();
|
|
81
|
+
const payload = JSON.stringify(requestWithMeta);
|
|
82
|
+
timings.requestStringifyMs = nowMs() - stringifyStart;
|
|
83
|
+
timings.sendStart = nowMs();
|
|
84
|
+
req.send(payload, "utf-8");
|
|
85
|
+
const response = await withTimeout(req.reply("utf-8"), options?.timeout);
|
|
86
|
+
timings.firstResponseAt = nowMs();
|
|
87
|
+
const parseStart = nowMs();
|
|
88
|
+
const rawParsed = JSON.parse(response?.toString() || "{}");
|
|
89
|
+
timings.responseJsonParseMs = nowMs() - parseStart;
|
|
90
|
+
const responseMeta = extractProfilingMeta(rawParsed);
|
|
91
|
+
const cleanPayload = stripProfilingMeta(rawParsed);
|
|
92
|
+
const zodValidateStart = nowMs();
|
|
93
|
+
const resPayload = responseSchema.parse(cleanPayload);
|
|
94
|
+
timings.responseZodValidationMs = nowMs() - zodValidateStart;
|
|
95
|
+
timings.requestEnd = nowMs();
|
|
96
|
+
logger.debug("ResPayload", { type: resPayload.type });
|
|
97
|
+
recordClientEvents(timings, responseMeta);
|
|
98
|
+
checkAndThrowError(resPayload);
|
|
99
|
+
return resPayload;
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
if (timings.requestEnd === undefined) {
|
|
103
|
+
const base = {
|
|
104
|
+
ts: nowMs(),
|
|
105
|
+
op: timings.requestType,
|
|
106
|
+
kind: "rpc",
|
|
107
|
+
profileId: timings.profileId,
|
|
108
|
+
};
|
|
109
|
+
recordFailure(base, timings.requestStart, error);
|
|
110
|
+
}
|
|
111
|
+
throw error;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
export async function* stream(request, options = {}, rpc) {
|
|
115
|
+
const ctx = await prepareRPCContext(request.type, options?.profiling, rpc);
|
|
116
|
+
if (!ctx.profilingEnabled) {
|
|
117
|
+
yield* streamBase(request, ctx.rpc, options, ctx.signalDisable);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
yield* streamProfiled(request, ctx.rpc, options);
|
|
121
|
+
}
|
|
122
|
+
async function* streamBase(request, rpc, options = {}, signalDisable = false) {
|
|
38
123
|
const parsedRequest = requestSchema.parse(request);
|
|
39
|
-
const
|
|
40
|
-
const req = rpcInstance.request(getNextCommandId());
|
|
124
|
+
const req = rpc.request(getNextCommandId());
|
|
41
125
|
logger.debug("RPC Client streaming:", summarizeRequest(request));
|
|
42
|
-
|
|
126
|
+
const payloadObj = signalDisable
|
|
127
|
+
? injectProfilingMetaIntoObject(parsedRequest, createProfilingDisabledMeta())
|
|
128
|
+
: parsedRequest;
|
|
129
|
+
req.send(JSON.stringify(payloadObj), "utf-8");
|
|
43
130
|
const responseStream = req.createResponseStream({ encoding: "utf-8" });
|
|
44
131
|
let buffer = "";
|
|
45
132
|
async function* processStream() {
|
|
@@ -62,9 +149,84 @@ export async function* stream(request, rpc, options = {}) {
|
|
|
62
149
|
}
|
|
63
150
|
}
|
|
64
151
|
}
|
|
152
|
+
async function* streamProfiled(request, rpc, options = {}) {
|
|
153
|
+
const requestType = request.type;
|
|
154
|
+
const profileId = createProfileId();
|
|
155
|
+
const includeServer = shouldIncludeServerBreakdown(options?.profiling);
|
|
156
|
+
const timings = createClientStreamTimings(profileId, requestType);
|
|
157
|
+
let profilingMeta = undefined;
|
|
158
|
+
try {
|
|
159
|
+
const zodStart = nowMs();
|
|
160
|
+
const parsedRequest = requestSchema.parse(request);
|
|
161
|
+
timings.requestZodValidationMs = nowMs() - zodStart;
|
|
162
|
+
const req = rpc.request(getNextCommandId());
|
|
163
|
+
logger.debug("RPC Client streaming:", summarizeRequest(request));
|
|
164
|
+
const requestMeta = createProfilingMeta(profileId, includeServer);
|
|
165
|
+
const requestWithMeta = injectProfilingMetaIntoObject(parsedRequest, requestMeta);
|
|
166
|
+
const stringifyStart = nowMs();
|
|
167
|
+
const payload = JSON.stringify(requestWithMeta);
|
|
168
|
+
timings.requestStringifyMs = nowMs() - stringifyStart;
|
|
169
|
+
timings.sendStart = nowMs();
|
|
170
|
+
req.send(payload, "utf-8");
|
|
171
|
+
const responseStream = req.createResponseStream({ encoding: "utf-8" });
|
|
172
|
+
let buffer = "";
|
|
173
|
+
async function* processStream() {
|
|
174
|
+
for await (const chunk of responseStream) {
|
|
175
|
+
yield chunk;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
const streamWithTimeout = withTimeoutStream(processStream(), options?.timeout);
|
|
179
|
+
for await (const chunk of streamWithTimeout) {
|
|
180
|
+
const chunkTime = nowMs();
|
|
181
|
+
if (timings.firstChunkAt === undefined) {
|
|
182
|
+
timings.firstChunkAt = chunkTime;
|
|
183
|
+
}
|
|
184
|
+
timings.lastChunkAt = chunkTime;
|
|
185
|
+
buffer += chunk.toString();
|
|
186
|
+
const lines = buffer.split("\n");
|
|
187
|
+
buffer = lines.pop() || "";
|
|
188
|
+
for (const line of lines) {
|
|
189
|
+
if (line.trim()) {
|
|
190
|
+
const rawParsed = JSON.parse(line);
|
|
191
|
+
const chunkMeta = extractProfilingMeta(rawParsed);
|
|
192
|
+
if (chunkMeta) {
|
|
193
|
+
profilingMeta = chunkMeta;
|
|
194
|
+
}
|
|
195
|
+
if (rawParsed[PROFILING_TRAILER_KEY] === true)
|
|
196
|
+
continue;
|
|
197
|
+
const cleanPayload = stripProfilingMeta(rawParsed);
|
|
198
|
+
const response = responseSchema.parse(cleanPayload);
|
|
199
|
+
timings.chunkCount++;
|
|
200
|
+
checkAndThrowError(response);
|
|
201
|
+
yield response;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
catch (error) {
|
|
207
|
+
if (timings.requestEnd === undefined) {
|
|
208
|
+
const base = {
|
|
209
|
+
ts: nowMs(),
|
|
210
|
+
op: timings.requestType,
|
|
211
|
+
kind: "rpc",
|
|
212
|
+
profileId: timings.profileId,
|
|
213
|
+
};
|
|
214
|
+
recordFailure(base, timings.requestStart, error);
|
|
215
|
+
}
|
|
216
|
+
throw error;
|
|
217
|
+
}
|
|
218
|
+
finally {
|
|
219
|
+
if (timings.chunkCount > 0) {
|
|
220
|
+
timings.requestEnd = nowMs();
|
|
221
|
+
recordClientStreamEvents(timings, profilingMeta);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
65
225
|
export async function close() {
|
|
66
226
|
if (!rpcInstance)
|
|
67
227
|
return;
|
|
68
228
|
rpcInstance = null;
|
|
229
|
+
firstConnectionPending = true;
|
|
230
|
+
resetConnectionTracking();
|
|
69
231
|
await closeRPC();
|
|
70
232
|
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { close, completion, LLAMA_3_2_1B_INST_Q4_0, loadModel, profiler, } from "@qvac/sdk";
|
|
2
|
+
const topicHex = process.argv[2];
|
|
3
|
+
if (!topicHex) {
|
|
4
|
+
console.error("❌ Usage: bun run consumer-profiled.ts <topic> <publicKey>");
|
|
5
|
+
process.exit(1);
|
|
6
|
+
}
|
|
7
|
+
const providerPublicKey = process.argv[3];
|
|
8
|
+
if (!providerPublicKey) {
|
|
9
|
+
console.error("❌ Usage: bun run consumer-profiled.ts <topic> <publicKey>");
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
try {
|
|
13
|
+
profiler.enable({ mode: "verbose", includeServerBreakdown: true });
|
|
14
|
+
console.log("✓ Profiler enabled");
|
|
15
|
+
console.log(`\n📡 Topic: ${topicHex}`);
|
|
16
|
+
console.log(`🔑 Provider: ${providerPublicKey}\n`);
|
|
17
|
+
console.log("→ Loading model (delegated, unary)...");
|
|
18
|
+
const modelId = await loadModel({
|
|
19
|
+
modelSrc: LLAMA_3_2_1B_INST_Q4_0,
|
|
20
|
+
modelType: "llm",
|
|
21
|
+
delegate: {
|
|
22
|
+
topic: topicHex,
|
|
23
|
+
providerPublicKey,
|
|
24
|
+
timeout: 30_000,
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
console.log(`✓ Model loaded: ${modelId}\n`);
|
|
28
|
+
console.log("→ Running completion (delegated, streamed)...");
|
|
29
|
+
const response = completion({
|
|
30
|
+
modelId,
|
|
31
|
+
history: [{ role: "user", content: "Say hello in exactly 5 words." }],
|
|
32
|
+
stream: true,
|
|
33
|
+
});
|
|
34
|
+
process.stdout.write(" Response: ");
|
|
35
|
+
for await (const token of response.tokenStream) {
|
|
36
|
+
process.stdout.write(token);
|
|
37
|
+
}
|
|
38
|
+
await response.stats;
|
|
39
|
+
console.log("\n✓ Completion done\n");
|
|
40
|
+
console.log("=== Profiler Summary ===");
|
|
41
|
+
console.log(profiler.exportSummary());
|
|
42
|
+
console.log("=== Profiler Table ===");
|
|
43
|
+
console.log(profiler.exportTable());
|
|
44
|
+
// Look for delegation-specific metrics
|
|
45
|
+
const json = profiler.exportJSON();
|
|
46
|
+
const delegationMetrics = Object.keys(json.aggregates).filter((k) => k.includes("delegation") || k.includes("delegated"));
|
|
47
|
+
if (delegationMetrics.length > 0) {
|
|
48
|
+
console.log("=== Delegation Metrics ===");
|
|
49
|
+
for (const key of delegationMetrics) {
|
|
50
|
+
const agg = json.aggregates[key];
|
|
51
|
+
if (agg) {
|
|
52
|
+
console.log(` ${key}: ${agg.avg.toFixed(2)}ms (count: ${agg.count})`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
console.log("⚠️ No delegation-specific metrics found");
|
|
58
|
+
console.log(" (delegation profiling may need to be triggered)");
|
|
59
|
+
}
|
|
60
|
+
profiler.disable();
|
|
61
|
+
void close();
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
console.error("❌ Error:", error);
|
|
65
|
+
profiler.disable();
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
@@ -10,9 +10,9 @@ try {
|
|
|
10
10
|
const modelId = await loadModel({
|
|
11
11
|
modelSrc: SMOLVLM2_500M_MULTIMODAL_Q8_0,
|
|
12
12
|
modelType: "llm",
|
|
13
|
-
projectionModelSrc: MMPROJ_SMOLVLM2_500M_MULTIMODAL_Q8_0,
|
|
14
13
|
modelConfig: {
|
|
15
14
|
ctx_size: 1024,
|
|
15
|
+
projectionModelSrc: MMPROJ_SMOLVLM2_500M_MULTIMODAL_Q8_0,
|
|
16
16
|
},
|
|
17
17
|
onProgress: (progress) => {
|
|
18
18
|
console.log(`Loading: ${progress.percentage.toFixed(1)}%`);
|
|
@@ -1,18 +1,50 @@
|
|
|
1
|
-
import { LLAMA_3_2_1B_INST_Q4_0,
|
|
1
|
+
import { LLAMA_3_2_1B_INST_Q4_0, WHISPER_TINY, VAD_SILERO_5_1_2, GTE_LARGE_FP16, downloadAsset, close, } from "@qvac/sdk";
|
|
2
|
+
function now() {
|
|
3
|
+
return Date.now();
|
|
4
|
+
}
|
|
5
|
+
const assets = [
|
|
6
|
+
{ name: "Llama 3.2 1B", src: LLAMA_3_2_1B_INST_Q4_0 },
|
|
7
|
+
{ name: "Whisper Tiny", src: WHISPER_TINY },
|
|
8
|
+
{ name: "VAD Silero", src: VAD_SILERO_5_1_2 },
|
|
9
|
+
{ name: "GTE Large FP16", src: GTE_LARGE_FP16 },
|
|
10
|
+
];
|
|
11
|
+
const timers = {};
|
|
12
|
+
console.log(`\n=== Parallel Download (${assets.length} assets) ===\n`);
|
|
13
|
+
const wallStart = now();
|
|
2
14
|
try {
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
15
|
+
const promises = assets.map((asset) => {
|
|
16
|
+
timers[asset.name] = { start: now() };
|
|
17
|
+
return downloadAsset({
|
|
18
|
+
assetSrc: asset.src,
|
|
19
|
+
onProgress: (progress) => {
|
|
20
|
+
const t = timers[asset.name];
|
|
21
|
+
if (t.firstProgress == null) {
|
|
22
|
+
t.firstProgress = now();
|
|
23
|
+
console.log(`[${asset.name}] first progress at ${((t.firstProgress - wallStart) / 1000).toFixed(1)}s — ${progress.percentage}%`);
|
|
24
|
+
}
|
|
25
|
+
if (progress.percentage === 100 && t.end == null) {
|
|
26
|
+
t.end = now();
|
|
27
|
+
console.log(`[${asset.name}] done at ${((t.end - wallStart) / 1000).toFixed(1)}s`);
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
});
|
|
14
31
|
});
|
|
15
|
-
await Promise.
|
|
32
|
+
const results = await Promise.allSettled(promises);
|
|
33
|
+
const wallEnd = now();
|
|
34
|
+
console.log(`\n=== Results ===\n`);
|
|
35
|
+
for (let i = 0; i < assets.length; i++) {
|
|
36
|
+
const asset = assets[i];
|
|
37
|
+
const result = results[i];
|
|
38
|
+
const t = timers[asset.name];
|
|
39
|
+
const status = result.status === "fulfilled" ? "OK" : "FAILED";
|
|
40
|
+
const reason = result.status === "rejected" ? ` — ${result.reason}` : "";
|
|
41
|
+
const timeToFirst = t.firstProgress != null
|
|
42
|
+
? `${((t.firstProgress - t.start) / 1000).toFixed(1)}s`
|
|
43
|
+
: "N/A";
|
|
44
|
+
const total = t.end != null ? `${((t.end - t.start) / 1000).toFixed(1)}s` : "N/A";
|
|
45
|
+
console.log(`${status} ${asset.name}: first-progress=${timeToFirst}, total=${total}${reason}`);
|
|
46
|
+
}
|
|
47
|
+
console.log(`\nWall time: ${((wallEnd - wallStart) / 1000).toFixed(1)}s`);
|
|
16
48
|
void close();
|
|
17
49
|
}
|
|
18
50
|
catch (error) {
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { completion, loadModel, unloadModel, LLAMA_3_2_1B_INST_Q4_0, profiler, } from "@qvac/sdk";
|
|
2
|
+
try {
|
|
3
|
+
// Enable profiling globally
|
|
4
|
+
profiler.enable({
|
|
5
|
+
mode: "verbose",
|
|
6
|
+
includeServerBreakdown: true,
|
|
7
|
+
});
|
|
8
|
+
console.log("Profiler enabled:", profiler.isEnabled());
|
|
9
|
+
const modelId = await loadModel({
|
|
10
|
+
modelSrc: LLAMA_3_2_1B_INST_Q4_0,
|
|
11
|
+
modelType: "llm",
|
|
12
|
+
onProgress: (p) => console.log(` ${p.percentage.toFixed(1)}%`),
|
|
13
|
+
});
|
|
14
|
+
console.log("Model loaded:", modelId);
|
|
15
|
+
console.log("\n→ Running completion...");
|
|
16
|
+
const result = completion({
|
|
17
|
+
modelId,
|
|
18
|
+
history: [{ role: "user", content: "Say hello in one sentence." }],
|
|
19
|
+
stream: true,
|
|
20
|
+
});
|
|
21
|
+
for await (const token of result.tokenStream) {
|
|
22
|
+
process.stdout.write(token);
|
|
23
|
+
}
|
|
24
|
+
console.log();
|
|
25
|
+
await unloadModel({ modelId });
|
|
26
|
+
// Export profiling data
|
|
27
|
+
console.log("\n=== Profiler Summary ===");
|
|
28
|
+
console.log(profiler.exportSummary());
|
|
29
|
+
console.log("\n=== Profiler Table ===");
|
|
30
|
+
console.log(profiler.exportTable());
|
|
31
|
+
const json = profiler.exportJSON();
|
|
32
|
+
console.log("\n=== Load Model Metrics ===");
|
|
33
|
+
// Filter for operation-level event (kind: "handler"), not RPC phase events
|
|
34
|
+
const loadModelEvent = json.recentEvents?.find((e) => e.op === "loadModel" && e.kind === "handler");
|
|
35
|
+
if (loadModelEvent) {
|
|
36
|
+
const tags = loadModelEvent.tags ?? {};
|
|
37
|
+
const gauges = loadModelEvent.gauges ?? {};
|
|
38
|
+
console.log(" sourceType:", tags["sourceType"] ?? "(not set)");
|
|
39
|
+
console.log(" cacheHit:", tags["cacheHit"] ?? "(not set)");
|
|
40
|
+
console.log(" totalLoadTime:", gauges["totalLoadTime"], "ms");
|
|
41
|
+
console.log(" modelInitializationTime:", gauges["modelInitializationTime"], "ms");
|
|
42
|
+
if (tags["cacheHit"] !== "true") {
|
|
43
|
+
console.log(" downloadTime:", gauges["downloadTime"] ?? "(cached)", "ms");
|
|
44
|
+
console.log(" totalBytesDownloaded:", gauges["totalBytesDownloaded"] ?? "(cached)");
|
|
45
|
+
console.log(" downloadSpeedBps:", gauges["downloadSpeedBps"] ?? "(cached)");
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
console.log(" (download metrics omitted - cache hit)");
|
|
49
|
+
}
|
|
50
|
+
if (gauges["checksumValidationTime"] !== undefined) {
|
|
51
|
+
console.log(" checksumValidationTime:", gauges["checksumValidationTime"], "ms");
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
console.log(" (no loadModel handler event captured)");
|
|
56
|
+
// Debug: show what ops are available
|
|
57
|
+
const ops = [...new Set(json.recentEvents?.map((e) => `${e.op}:${e.kind}`) ?? [])];
|
|
58
|
+
console.log(" Available ops:", ops.join(", "));
|
|
59
|
+
}
|
|
60
|
+
console.log("\n=== Profiler JSON (structure) ===");
|
|
61
|
+
console.log(" aggregates:", Object.keys(json.aggregates).length, "metrics");
|
|
62
|
+
console.log(" recentEvents:", json.recentEvents?.length ?? 0, "events");
|
|
63
|
+
console.log(" config:", json.config);
|
|
64
|
+
// Disable profiling
|
|
65
|
+
profiler.disable();
|
|
66
|
+
console.log("\nProfiler disabled:", !profiler.isEnabled());
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
console.error("Error:", error);
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { embed, loadModel, unloadModel, GTE_LARGE_FP16, profiler, } from "@qvac/sdk";
|
|
2
|
+
try {
|
|
3
|
+
profiler.disable();
|
|
4
|
+
console.log("Profiler globally enabled:", profiler.isEnabled());
|
|
5
|
+
const modelId = await loadModel({
|
|
6
|
+
modelSrc: GTE_LARGE_FP16,
|
|
7
|
+
modelType: "embeddings",
|
|
8
|
+
onProgress: (p) => console.log(` ${p.percentage.toFixed(1)}%`),
|
|
9
|
+
});
|
|
10
|
+
console.log("Model loaded:", modelId);
|
|
11
|
+
console.log("\n=== Embed with per-call profiling ===");
|
|
12
|
+
const embedding1 = await embed({ modelId, text: "Profile this specific call" }, { profiling: { enabled: true, includeServerBreakdown: true } });
|
|
13
|
+
console.log("Embedding dimensions:", embedding1.length);
|
|
14
|
+
console.log("\n=== Embed without profiling ===");
|
|
15
|
+
const embedding2 = await embed({
|
|
16
|
+
modelId,
|
|
17
|
+
text: "This call is not profiled",
|
|
18
|
+
});
|
|
19
|
+
console.log("Embedding dimensions:", embedding2.length);
|
|
20
|
+
console.log("\n=== Embed with profiling explicitly disabled ===");
|
|
21
|
+
const embedding3 = await embed({ modelId, text: "Profiling explicitly disabled for this call" }, { profiling: { enabled: false } });
|
|
22
|
+
console.log("Embedding dimensions:", embedding3.length);
|
|
23
|
+
await unloadModel({ modelId });
|
|
24
|
+
console.log("\n=== Profiler Summary (per-call data only) ===");
|
|
25
|
+
console.log(profiler.exportSummary());
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
console.error("Error:", error);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|