@qvac/sdk 0.7.0 → 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 +14 -17
- 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,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON, table, and summary export utilities for profiling data.
|
|
3
|
+
*/
|
|
4
|
+
import type { ProfilerExport } from "./types";
|
|
5
|
+
export declare function exportJSON(options?: {
|
|
6
|
+
includeRecentEvents?: boolean;
|
|
7
|
+
}): ProfilerExport;
|
|
8
|
+
export declare function exportTable(): string;
|
|
9
|
+
export declare function exportSummary(): string;
|
|
10
|
+
//# sourceMappingURL=exporters.d.ts.map
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON, table, and summary export utilities for profiling data.
|
|
3
|
+
*/
|
|
4
|
+
import { getEffectiveConfig, getAggregates, getRecentEvents, } from "./controller.js";
|
|
5
|
+
import { getDroppedCount, getEventCount } from "./aggregator.js";
|
|
6
|
+
import { nowMs, getClockSource, isMonotonic } from "./clock.js";
|
|
7
|
+
export function exportJSON(options) {
|
|
8
|
+
const config = getEffectiveConfig();
|
|
9
|
+
const includeRecent = options?.includeRecentEvents ?? true;
|
|
10
|
+
const result = {
|
|
11
|
+
config,
|
|
12
|
+
aggregates: getAggregates(),
|
|
13
|
+
exportedAt: nowMs(),
|
|
14
|
+
};
|
|
15
|
+
if (includeRecent && config.mode === "verbose") {
|
|
16
|
+
result.recentEvents = getRecentEvents();
|
|
17
|
+
}
|
|
18
|
+
return result;
|
|
19
|
+
}
|
|
20
|
+
function aggregateMatchingStats(aggregates, predicate) {
|
|
21
|
+
const matches = Object.entries(aggregates).filter(([key]) => predicate(key));
|
|
22
|
+
if (matches.length === 0) {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
let count = 0;
|
|
26
|
+
let sum = 0;
|
|
27
|
+
let min = Infinity;
|
|
28
|
+
let max = -Infinity;
|
|
29
|
+
let last = 0;
|
|
30
|
+
for (const [, stats] of matches) {
|
|
31
|
+
count += stats.count;
|
|
32
|
+
sum += stats.sum;
|
|
33
|
+
if (stats.count > 0) {
|
|
34
|
+
if (stats.min < min)
|
|
35
|
+
min = stats.min;
|
|
36
|
+
if (stats.max > max)
|
|
37
|
+
max = stats.max;
|
|
38
|
+
last = stats.last;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
count,
|
|
43
|
+
min: count > 0 ? min : 0,
|
|
44
|
+
max: count > 0 ? max : 0,
|
|
45
|
+
avg: count > 0 ? sum / count : 0,
|
|
46
|
+
sum,
|
|
47
|
+
last,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function formatDuration(ms) {
|
|
51
|
+
if (ms < 1) {
|
|
52
|
+
return `${(ms * 1000).toFixed(0)}μs`;
|
|
53
|
+
}
|
|
54
|
+
if (ms < 1000) {
|
|
55
|
+
return `${ms.toFixed(1)}ms`;
|
|
56
|
+
}
|
|
57
|
+
if (ms < 60000) {
|
|
58
|
+
return `${(ms / 1000).toFixed(2)}s`;
|
|
59
|
+
}
|
|
60
|
+
return `${(ms / 60000).toFixed(2)}m`;
|
|
61
|
+
}
|
|
62
|
+
function formatBytes(bytes) {
|
|
63
|
+
if (bytes < 1024)
|
|
64
|
+
return `${bytes.toFixed(0)} B`;
|
|
65
|
+
if (bytes < 1024 * 1024)
|
|
66
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
67
|
+
if (bytes < 1024 * 1024 * 1024)
|
|
68
|
+
return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
|
|
69
|
+
return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`;
|
|
70
|
+
}
|
|
71
|
+
function formatThroughput(bps) {
|
|
72
|
+
if (bps < 1024)
|
|
73
|
+
return `${bps.toFixed(0)} B/s`;
|
|
74
|
+
if (bps < 1024 * 1024)
|
|
75
|
+
return `${(bps / 1024).toFixed(1)} KB/s`;
|
|
76
|
+
if (bps < 1024 * 1024 * 1024)
|
|
77
|
+
return `${(bps / (1024 * 1024)).toFixed(2)} MB/s`;
|
|
78
|
+
return `${(bps / (1024 * 1024 * 1024)).toFixed(2)} GB/s`;
|
|
79
|
+
}
|
|
80
|
+
function formatNumber(n) {
|
|
81
|
+
if (Number.isInteger(n)) {
|
|
82
|
+
return n.toLocaleString();
|
|
83
|
+
}
|
|
84
|
+
if (n === 0)
|
|
85
|
+
return "0";
|
|
86
|
+
if (Math.abs(n) < 0.01)
|
|
87
|
+
return n.toExponential(2);
|
|
88
|
+
if (Math.abs(n) < 1)
|
|
89
|
+
return n.toFixed(3);
|
|
90
|
+
if (Math.abs(n) < 100)
|
|
91
|
+
return n.toFixed(2);
|
|
92
|
+
return n.toFixed(1);
|
|
93
|
+
}
|
|
94
|
+
function detectMetricType(metricName) {
|
|
95
|
+
const lowerName = metricName.toLowerCase();
|
|
96
|
+
if (lowerName.includes("bps") || lowerName.includes("speed")) {
|
|
97
|
+
return "throughput";
|
|
98
|
+
}
|
|
99
|
+
if (lowerName.includes("bytes") || lowerName.includes("downloaded") || lowerName.includes("size")) {
|
|
100
|
+
return "bytes";
|
|
101
|
+
}
|
|
102
|
+
if (lowerName.endsWith("time") ||
|
|
103
|
+
lowerName.endsWith("ms") ||
|
|
104
|
+
lowerName.endsWith("duration") ||
|
|
105
|
+
lowerName.includes("ttfb") ||
|
|
106
|
+
lowerName.includes("latency") ||
|
|
107
|
+
lowerName.includes("wait") ||
|
|
108
|
+
lowerName.includes("overhead") ||
|
|
109
|
+
lowerName.includes("parse") ||
|
|
110
|
+
lowerName.includes("stringify") ||
|
|
111
|
+
lowerName.includes("validation") ||
|
|
112
|
+
lowerName.includes("execution") ||
|
|
113
|
+
lowerName.includes("serialization") ||
|
|
114
|
+
lowerName.includes("connection")) {
|
|
115
|
+
return "duration";
|
|
116
|
+
}
|
|
117
|
+
if (lowerName.includes("count") || lowerName.includes("token")) {
|
|
118
|
+
return "number";
|
|
119
|
+
}
|
|
120
|
+
// Default to duration for unknown metrics (most profiling is timing)
|
|
121
|
+
return "duration";
|
|
122
|
+
}
|
|
123
|
+
function formatMetricValue(value, metricName) {
|
|
124
|
+
const type = detectMetricType(metricName);
|
|
125
|
+
switch (type) {
|
|
126
|
+
case "bytes":
|
|
127
|
+
return formatBytes(value);
|
|
128
|
+
case "throughput":
|
|
129
|
+
return formatThroughput(value);
|
|
130
|
+
case "number":
|
|
131
|
+
return formatNumber(value);
|
|
132
|
+
case "duration":
|
|
133
|
+
default:
|
|
134
|
+
return formatDuration(value);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
function pad(s, len, align = "left") {
|
|
138
|
+
if (s.length >= len)
|
|
139
|
+
return s.substring(0, len);
|
|
140
|
+
const spaces = " ".repeat(len - s.length);
|
|
141
|
+
return align === "left" ? s + spaces : spaces + s;
|
|
142
|
+
}
|
|
143
|
+
export function exportTable() {
|
|
144
|
+
const aggregates = getAggregates();
|
|
145
|
+
const entries = Object.entries(aggregates);
|
|
146
|
+
if (entries.length === 0) {
|
|
147
|
+
return "No profiling data recorded.";
|
|
148
|
+
}
|
|
149
|
+
const metricWidth = 40;
|
|
150
|
+
const numWidth = 12;
|
|
151
|
+
const header = [
|
|
152
|
+
pad("Metric", metricWidth),
|
|
153
|
+
pad("Count", numWidth, "right"),
|
|
154
|
+
pad("Min", numWidth, "right"),
|
|
155
|
+
pad("Max", numWidth, "right"),
|
|
156
|
+
pad("Avg", numWidth, "right"),
|
|
157
|
+
pad("Total", numWidth, "right"),
|
|
158
|
+
].join(" | ");
|
|
159
|
+
const separator = "-".repeat(header.length);
|
|
160
|
+
const rows = entries
|
|
161
|
+
.sort((a, b) => a[0].localeCompare(b[0]))
|
|
162
|
+
.map(([metric, stats]) => {
|
|
163
|
+
return [
|
|
164
|
+
pad(metric, metricWidth),
|
|
165
|
+
pad(formatNumber(stats.count), numWidth, "right"),
|
|
166
|
+
pad(formatMetricValue(stats.min, metric), numWidth, "right"),
|
|
167
|
+
pad(formatMetricValue(stats.max, metric), numWidth, "right"),
|
|
168
|
+
pad(formatMetricValue(stats.avg, metric), numWidth, "right"),
|
|
169
|
+
pad(formatMetricValue(stats.sum, metric), numWidth, "right"),
|
|
170
|
+
].join(" | ");
|
|
171
|
+
});
|
|
172
|
+
return [separator, header, separator, ...rows, separator].join("\n");
|
|
173
|
+
}
|
|
174
|
+
export function exportSummary() {
|
|
175
|
+
const aggregates = getAggregates();
|
|
176
|
+
const config = getEffectiveConfig();
|
|
177
|
+
const eventCount = getEventCount();
|
|
178
|
+
const droppedCount = getDroppedCount();
|
|
179
|
+
const lines = [
|
|
180
|
+
"=".repeat(60),
|
|
181
|
+
"PROFILER SUMMARY",
|
|
182
|
+
"=".repeat(60),
|
|
183
|
+
"",
|
|
184
|
+
"Session:",
|
|
185
|
+
` Status: ${config.enabled ? "enabled" : "disabled"}`,
|
|
186
|
+
` Mode: ${config.mode}`,
|
|
187
|
+
` Clock: ${getClockSource()} (monotonic: ${isMonotonic()})`,
|
|
188
|
+
` Events: ${eventCount.toLocaleString()}`,
|
|
189
|
+
` Dropped: ${droppedCount.toLocaleString()}`,
|
|
190
|
+
"",
|
|
191
|
+
];
|
|
192
|
+
const keyMetrics = [
|
|
193
|
+
{
|
|
194
|
+
label: "RPC Total",
|
|
195
|
+
stats: aggregateMatchingStats(aggregates, (key) => key.endsWith(".totalClientTime")),
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
label: "Handler",
|
|
199
|
+
stats: aggregateMatchingStats(aggregates, (key) => key.endsWith(".server.handlerExecution") || !key.includes(".")),
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
label: "Model Load",
|
|
203
|
+
stats: aggregateMatchingStats(aggregates, (key) => key === "load.totalTime" || key.endsWith(".load.totalTime")),
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
label: "Download",
|
|
207
|
+
stats: aggregateMatchingStats(aggregates, (key) => key === "download.time" || key.endsWith(".download.time")),
|
|
208
|
+
},
|
|
209
|
+
];
|
|
210
|
+
const hasMetrics = keyMetrics.some((m) => m.stats);
|
|
211
|
+
if (hasMetrics) {
|
|
212
|
+
lines.push("Key Metrics:");
|
|
213
|
+
lines.push("-".repeat(60));
|
|
214
|
+
lines.push(" " +
|
|
215
|
+
"Metric".padEnd(18) +
|
|
216
|
+
"Samples".padStart(10) +
|
|
217
|
+
"Avg".padStart(12) +
|
|
218
|
+
"Total".padStart(12));
|
|
219
|
+
lines.push("-".repeat(60));
|
|
220
|
+
for (const { label, stats } of keyMetrics) {
|
|
221
|
+
if (stats) {
|
|
222
|
+
const name = label.padEnd(18);
|
|
223
|
+
const samples = String(stats.count).padStart(10);
|
|
224
|
+
const avg = formatDuration(stats.avg).padStart(12);
|
|
225
|
+
const total = formatDuration(stats.sum).padStart(12);
|
|
226
|
+
lines.push(` ${name}${samples}${avg}${total}`);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
lines.push("No metrics recorded yet.");
|
|
232
|
+
}
|
|
233
|
+
lines.push("");
|
|
234
|
+
lines.push("=".repeat(60));
|
|
235
|
+
return lines.join("\n");
|
|
236
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QVAC SDK Profiler
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```ts
|
|
6
|
+
* import { profiler } from "@qvac/sdk";
|
|
7
|
+
*
|
|
8
|
+
* profiler.enable({ mode: "summary" });
|
|
9
|
+
* // ... run SDK operations ...
|
|
10
|
+
* console.log(profiler.exportTable());
|
|
11
|
+
* profiler.disable();
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
import * as controller from "./controller";
|
|
15
|
+
import type { ProfilerRuntimeOptions, ProfilingEvent, ProfilerExport, AggregatedStats } from "./types";
|
|
16
|
+
export declare const profiler: {
|
|
17
|
+
enable: (options?: ProfilerRuntimeOptions) => void;
|
|
18
|
+
disable: () => void;
|
|
19
|
+
isEnabled: () => boolean;
|
|
20
|
+
exportJSON: (options?: {
|
|
21
|
+
includeRecentEvents?: boolean;
|
|
22
|
+
}) => ProfilerExport;
|
|
23
|
+
exportTable: () => string;
|
|
24
|
+
exportSummary: () => string;
|
|
25
|
+
onRecord: (callback: (event: ProfilingEvent) => void) => () => void;
|
|
26
|
+
getConfig: () => controller.ResolvedProfilerConfig;
|
|
27
|
+
getAggregates: () => Record<string, AggregatedStats>;
|
|
28
|
+
clear: () => void;
|
|
29
|
+
};
|
|
30
|
+
export type { ProfilerRuntimeOptions, ProfilingEvent, ProfilerExport, AggregatedStats, ProfilingEventKind, } from "./types";
|
|
31
|
+
export type { ProfilerMode } from "../schemas/index";
|
|
32
|
+
export { nowMs } from "./clock";
|
|
33
|
+
export { record, shouldProfile, shouldIncludeServerBreakdown, generateId, isEnabled, type ResolvedProfilerConfig, } from "./controller";
|
|
34
|
+
export { createProfilingMeta, createProfilingDisabledMeta, injectProfilingMetaIntoObject, extractProfilingMeta, stripProfilingMeta, } from "./envelope";
|
|
35
|
+
export { recordPhase, recordFailure, recordServerBreakdownPhases, recordDelegationBreakdownPhases, type BaseTimings, type BaseEvent, } from "./events";
|
|
36
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QVAC SDK Profiler
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```ts
|
|
6
|
+
* import { profiler } from "@qvac/sdk";
|
|
7
|
+
*
|
|
8
|
+
* profiler.enable({ mode: "summary" });
|
|
9
|
+
* // ... run SDK operations ...
|
|
10
|
+
* console.log(profiler.exportTable());
|
|
11
|
+
* profiler.disable();
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
import * as controller from "./controller.js";
|
|
15
|
+
import * as exporters from "./exporters.js";
|
|
16
|
+
export const profiler = {
|
|
17
|
+
enable: (options) => controller.enable(options),
|
|
18
|
+
disable: () => controller.disable(),
|
|
19
|
+
isEnabled: () => controller.isEnabled(),
|
|
20
|
+
exportJSON: (options) => exporters.exportJSON(options),
|
|
21
|
+
exportTable: () => exporters.exportTable(),
|
|
22
|
+
exportSummary: () => exporters.exportSummary(),
|
|
23
|
+
onRecord: (callback) => controller.onRecord(callback),
|
|
24
|
+
getConfig: () => controller.getEffectiveConfig(),
|
|
25
|
+
getAggregates: () => controller.getAggregates(),
|
|
26
|
+
clear: () => controller.clear(),
|
|
27
|
+
};
|
|
28
|
+
export { nowMs } from "./clock.js";
|
|
29
|
+
export { record, shouldProfile, shouldIncludeServerBreakdown, generateId, isEnabled, } from "./controller.js";
|
|
30
|
+
export { createProfilingMeta, createProfilingDisabledMeta, injectProfilingMetaIntoObject, extractProfilingMeta, stripProfilingMeta, } from "./envelope.js";
|
|
31
|
+
export { recordPhase, recordFailure, recordServerBreakdownPhases, recordDelegationBreakdownPhases, } from "./events.js";
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* O(1) bounded buffer for event storage.
|
|
3
|
+
* Oldest events are overwritten when full.
|
|
4
|
+
*/
|
|
5
|
+
export interface RingBufferState<T> {
|
|
6
|
+
buffer: (T | undefined)[];
|
|
7
|
+
capacity: number;
|
|
8
|
+
head: number;
|
|
9
|
+
size: number;
|
|
10
|
+
totalPushed: number;
|
|
11
|
+
}
|
|
12
|
+
export declare function createRingBuffer<T>(capacity: number): RingBufferState<T>;
|
|
13
|
+
export declare function ringBufferPush<T>(state: RingBufferState<T>, item: T): T | undefined;
|
|
14
|
+
export declare function ringBufferToArray<T>(state: RingBufferState<T>): T[];
|
|
15
|
+
export declare function ringBufferGetRecent<T>(state: RingBufferState<T>, count: number): T[];
|
|
16
|
+
export declare function ringBufferClear<T>(state: RingBufferState<T>): void;
|
|
17
|
+
export declare function ringBufferDroppedCount<T>(state: RingBufferState<T>): number;
|
|
18
|
+
export declare function ringBufferResize<T>(state: RingBufferState<T>, newCapacity: number): RingBufferState<T>;
|
|
19
|
+
//# sourceMappingURL=ring-buffer.d.ts.map
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* O(1) bounded buffer for event storage.
|
|
3
|
+
* Oldest events are overwritten when full.
|
|
4
|
+
*/
|
|
5
|
+
import { ProfilerInvalidCapacityError } from "../utils/errors-client.js";
|
|
6
|
+
export function createRingBuffer(capacity) {
|
|
7
|
+
if (capacity < 1) {
|
|
8
|
+
throw new ProfilerInvalidCapacityError(1);
|
|
9
|
+
}
|
|
10
|
+
return {
|
|
11
|
+
buffer: new Array(capacity),
|
|
12
|
+
capacity,
|
|
13
|
+
head: 0,
|
|
14
|
+
size: 0,
|
|
15
|
+
totalPushed: 0,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
// Returns the overwritten item if buffer was full, undefined otherwise.
|
|
19
|
+
export function ringBufferPush(state, item) {
|
|
20
|
+
const overwritten = state.size === state.capacity ? state.buffer[state.head] : undefined;
|
|
21
|
+
state.buffer[state.head] = item;
|
|
22
|
+
state.head = (state.head + 1) % state.capacity;
|
|
23
|
+
state.size = Math.min(state.size + 1, state.capacity);
|
|
24
|
+
state.totalPushed++;
|
|
25
|
+
return overwritten;
|
|
26
|
+
}
|
|
27
|
+
// Returns all items in chronological order (oldest first).
|
|
28
|
+
export function ringBufferToArray(state) {
|
|
29
|
+
if (state.size === 0) {
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
const result = [];
|
|
33
|
+
const start = state.size === state.capacity
|
|
34
|
+
? state.head // Full: head points to oldest
|
|
35
|
+
: 0;
|
|
36
|
+
for (let i = 0; i < state.size; i++) {
|
|
37
|
+
const index = (start + i) % state.capacity;
|
|
38
|
+
const item = state.buffer[index];
|
|
39
|
+
if (item !== undefined) {
|
|
40
|
+
result.push(item);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
45
|
+
// Returns the most recent N items (newest first).
|
|
46
|
+
export function ringBufferGetRecent(state, count) {
|
|
47
|
+
if (state.size === 0 || count <= 0) {
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
const actualCount = Math.min(count, state.size);
|
|
51
|
+
const result = [];
|
|
52
|
+
for (let i = 0; i < actualCount; i++) {
|
|
53
|
+
const index = (state.head - 1 - i + state.capacity) % state.capacity;
|
|
54
|
+
const item = state.buffer[index];
|
|
55
|
+
if (item !== undefined) {
|
|
56
|
+
result.push(item);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
61
|
+
export function ringBufferClear(state) {
|
|
62
|
+
state.buffer = new Array(state.capacity);
|
|
63
|
+
state.head = 0;
|
|
64
|
+
state.size = 0;
|
|
65
|
+
state.totalPushed = 0;
|
|
66
|
+
}
|
|
67
|
+
export function ringBufferDroppedCount(state) {
|
|
68
|
+
return Math.max(0, state.totalPushed - state.capacity);
|
|
69
|
+
}
|
|
70
|
+
// Resizes the buffer, keeping the most recent items.
|
|
71
|
+
export function ringBufferResize(state, newCapacity) {
|
|
72
|
+
if (newCapacity < 1) {
|
|
73
|
+
throw new ProfilerInvalidCapacityError(1);
|
|
74
|
+
}
|
|
75
|
+
const items = ringBufferToArray(state);
|
|
76
|
+
const itemsToKeep = items.slice(-newCapacity);
|
|
77
|
+
const newState = createRingBuffer(newCapacity);
|
|
78
|
+
for (const item of itemsToKeep) {
|
|
79
|
+
ringBufferPush(newState, item);
|
|
80
|
+
}
|
|
81
|
+
newState.totalPushed = state.totalPushed;
|
|
82
|
+
return newState;
|
|
83
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export type ProfilingEventKind = "rpc" | "handler" | "download" | "load" | "delegation";
|
|
2
|
+
export interface ProfilingEvent {
|
|
3
|
+
/** Timestamp when event was recorded (monotonic ms) */
|
|
4
|
+
ts: number;
|
|
5
|
+
op: string;
|
|
6
|
+
kind: ProfilingEventKind;
|
|
7
|
+
profileId?: string;
|
|
8
|
+
phase?: string;
|
|
9
|
+
ms?: number;
|
|
10
|
+
/** Count (e.g., chunks, tokens) */
|
|
11
|
+
count?: number;
|
|
12
|
+
bytes?: number;
|
|
13
|
+
/** Numeric gauges (e.g., throughput, token counters) */
|
|
14
|
+
gauges?: Record<string, number>;
|
|
15
|
+
/** String tags (e.g., handlerType, sourceType, modelId) */
|
|
16
|
+
tags?: Record<string, string>;
|
|
17
|
+
}
|
|
18
|
+
export interface ProfilerRuntimeOptions {
|
|
19
|
+
mode?: "summary" | "verbose";
|
|
20
|
+
includeServerBreakdown?: boolean;
|
|
21
|
+
operationFilters?: string[];
|
|
22
|
+
}
|
|
23
|
+
export interface AggregatedStats {
|
|
24
|
+
count: number;
|
|
25
|
+
min: number;
|
|
26
|
+
max: number;
|
|
27
|
+
avg: number;
|
|
28
|
+
sum: number;
|
|
29
|
+
last: number;
|
|
30
|
+
}
|
|
31
|
+
export interface ProfilerExport {
|
|
32
|
+
config: {
|
|
33
|
+
enabled: boolean;
|
|
34
|
+
mode: "summary" | "verbose";
|
|
35
|
+
includeServerBreakdown: boolean;
|
|
36
|
+
operationFilters: string[];
|
|
37
|
+
maxRecentEvents: number;
|
|
38
|
+
};
|
|
39
|
+
aggregates: Record<string, AggregatedStats>;
|
|
40
|
+
recentEvents?: ProfilingEvent[];
|
|
41
|
+
exportedAt: number;
|
|
42
|
+
}
|
|
43
|
+
export interface LoadTimingStats {
|
|
44
|
+
modelInitializationTimeMs?: number;
|
|
45
|
+
totalLoadTimeMs?: number;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|