@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
|
@@ -74,7 +74,7 @@ export type RegistryItem = {
|
|
|
74
74
|
blobBlockLength: number;
|
|
75
75
|
blobByteOffset: number;
|
|
76
76
|
modelId: string;
|
|
77
|
-
addon: "llm" | "whisper" | "embeddings" | "nmt" | "vad" | "tts" | "ocr" | "other";
|
|
77
|
+
addon: "llm" | "whisper" | "embeddings" | "nmt" | "vad" | "tts" | "ocr" | "parakeet" | "other";
|
|
78
78
|
expectedSize: number;
|
|
79
79
|
sha256Checksum: string;
|
|
80
80
|
engine: string;
|
|
@@ -103,7 +103,7 @@ export type ModelConstant = {
|
|
|
103
103
|
modelId: string;
|
|
104
104
|
expectedSize: number;
|
|
105
105
|
sha256Checksum: string;
|
|
106
|
-
addon: "llm" | "whisper" | "embeddings" | "nmt" | "vad" | "tts" | "ocr" | "other";
|
|
106
|
+
addon: "llm" | "whisper" | "embeddings" | "nmt" | "vad" | "tts" | "ocr" | "parakeet" | "other";
|
|
107
107
|
engine: string;
|
|
108
108
|
quantization: string;
|
|
109
109
|
params: string;
|
|
@@ -7,6 +7,17 @@ export declare function compareModels(remoteModels: ProcessedModel[], currentMod
|
|
|
7
7
|
export declare function assignNames(models: ProcessedModel[]): (ProcessedModel & {
|
|
8
8
|
name: string;
|
|
9
9
|
})[];
|
|
10
|
+
export declare function separateUpdates(added: (ProcessedModel & {
|
|
11
|
+
name: string;
|
|
12
|
+
})[], removed: CurrentModel[]): {
|
|
13
|
+
added: (ProcessedModel & {
|
|
14
|
+
name: string;
|
|
15
|
+
})[];
|
|
16
|
+
updated: (ProcessedModel & {
|
|
17
|
+
name: string;
|
|
18
|
+
})[];
|
|
19
|
+
removed: CurrentModel[];
|
|
20
|
+
};
|
|
10
21
|
export declare function createHistoryFile(added: (ProcessedModel & {
|
|
11
22
|
name: string;
|
|
12
23
|
})[], removed: CurrentModel[], currentModels: CurrentModel[], historyDir: string): string | null;
|
|
@@ -53,10 +53,21 @@ export function assignNames(models) {
|
|
|
53
53
|
}),
|
|
54
54
|
}));
|
|
55
55
|
}
|
|
56
|
+
export function separateUpdates(added, removed) {
|
|
57
|
+
const removedNames = new Set(removed.map((m) => m.name));
|
|
58
|
+
const addedNames = new Set(added.map((m) => m.name));
|
|
59
|
+
const updatedNames = new Set([...addedNames].filter((name) => removedNames.has(name)));
|
|
60
|
+
return {
|
|
61
|
+
added: added.filter((m) => !updatedNames.has(m.name)),
|
|
62
|
+
updated: added.filter((m) => updatedNames.has(m.name)),
|
|
63
|
+
removed: removed.filter((m) => !updatedNames.has(m.name)),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
56
66
|
export function createHistoryFile(added, removed, currentModels, historyDir) {
|
|
57
67
|
if (added.length === 0 && removed.length === 0) {
|
|
58
68
|
return null;
|
|
59
69
|
}
|
|
70
|
+
const { added: trulyAdded, updated, removed: trulyRemoved, } = separateUpdates(added, removed);
|
|
60
71
|
if (!fs.existsSync(historyDir)) {
|
|
61
72
|
fs.mkdirSync(historyDir, { recursive: true });
|
|
62
73
|
}
|
|
@@ -68,20 +79,28 @@ export function createHistoryFile(added, removed, currentModels, historyDir) {
|
|
|
68
79
|
let content = `commit=${fullHash}\n`;
|
|
69
80
|
content += `timestamp=${timestamp}\n`;
|
|
70
81
|
content += `previous_count=${currentModels.length}\n`;
|
|
71
|
-
content += `new_count=${currentModels.length +
|
|
82
|
+
content += `new_count=${currentModels.length + trulyAdded.length - trulyRemoved.length}\n`;
|
|
72
83
|
content += `\n`;
|
|
73
|
-
if (
|
|
84
|
+
if (trulyAdded.length > 0) {
|
|
74
85
|
content += `[added]\n`;
|
|
75
|
-
|
|
86
|
+
trulyAdded.forEach((m) => {
|
|
87
|
+
content += `${m.name}\n`;
|
|
88
|
+
});
|
|
89
|
+
content += `\n`;
|
|
90
|
+
}
|
|
91
|
+
if (updated.length > 0) {
|
|
92
|
+
content += `[updated]\n`;
|
|
93
|
+
updated.forEach((m) => {
|
|
76
94
|
content += `${m.name}\n`;
|
|
77
95
|
});
|
|
78
96
|
content += `\n`;
|
|
79
97
|
}
|
|
80
|
-
if (
|
|
98
|
+
if (trulyRemoved.length > 0) {
|
|
81
99
|
content += `[removed]\n`;
|
|
82
|
-
|
|
100
|
+
trulyRemoved.forEach((m) => {
|
|
83
101
|
content += `${m.name}\n`;
|
|
84
102
|
});
|
|
103
|
+
content += `\n`;
|
|
85
104
|
}
|
|
86
105
|
fs.writeFileSync(filepath, content);
|
|
87
106
|
return filepath;
|
|
@@ -2,8 +2,7 @@ import fs from "fs";
|
|
|
2
2
|
import { fileURLToPath } from "url";
|
|
3
3
|
import { execSync } from "child_process";
|
|
4
4
|
import { generateModelsFileContent } from "./codegen.js";
|
|
5
|
-
import {
|
|
6
|
-
import { assignNames, compareModels, createHistoryFile, loadCurrentModels, } from "./history.js";
|
|
5
|
+
import { assignNames, compareModels, createHistoryFile, loadCurrentModels, separateUpdates, } from "./history.js";
|
|
7
6
|
import { collectModels } from "./registry.js";
|
|
8
7
|
import { formatSize } from "./utils.js";
|
|
9
8
|
const OUTPUT_FILE = fileURLToPath(new URL("../registry/models.ts", import.meta.url));
|
|
@@ -34,32 +33,33 @@ async function checkOnly(nonBlocking = false, showDuplicates = false) {
|
|
|
34
33
|
process.exit(nonBlocking ? 0 : 1);
|
|
35
34
|
}
|
|
36
35
|
const { remoteModels, currentModels } = result;
|
|
37
|
-
const { added, removed } = compareModels(remoteModels, currentModels);
|
|
38
|
-
if (
|
|
36
|
+
const { added: rawAdded, removed: rawRemoved } = compareModels(remoteModels, currentModels);
|
|
37
|
+
if (rawAdded.length === 0 && rawRemoved.length === 0) {
|
|
39
38
|
console.log(`✅ Models are up to date (${remoteModels.length} models)`);
|
|
40
39
|
process.exit(0);
|
|
41
40
|
}
|
|
41
|
+
const addedWithNames = assignNames(rawAdded);
|
|
42
|
+
const { added, updated, removed } = separateUpdates(addedWithNames, rawRemoved);
|
|
42
43
|
console.log("");
|
|
43
44
|
console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
|
|
44
45
|
if (added.length > 0) {
|
|
45
46
|
console.log(`✨ ${added.length} new model${added.length === 1 ? "" : "s"} available:`);
|
|
46
|
-
const usedNames = new Set();
|
|
47
47
|
added.slice(0, 10).forEach((m) => {
|
|
48
|
-
|
|
49
|
-
path: m.registryPath,
|
|
50
|
-
engine: m.engine,
|
|
51
|
-
name: m.modelName,
|
|
52
|
-
quantization: m.quantization,
|
|
53
|
-
params: m.params,
|
|
54
|
-
tags: m.tags,
|
|
55
|
-
usedNames,
|
|
56
|
-
});
|
|
57
|
-
console.log(` + ${exportName} (${m.addon}, ${formatSize(m.expectedSize)})`);
|
|
48
|
+
console.log(` + ${m.name} (${m.addon}, ${formatSize(m.expectedSize)})`);
|
|
58
49
|
});
|
|
59
50
|
if (added.length > 10) {
|
|
60
51
|
console.log(` ... and ${added.length - 10} more`);
|
|
61
52
|
}
|
|
62
53
|
}
|
|
54
|
+
if (updated.length > 0) {
|
|
55
|
+
console.log(`\n🔄 ${updated.length} model${updated.length === 1 ? "" : "s"} updated:`);
|
|
56
|
+
updated.slice(0, 10).forEach((m) => {
|
|
57
|
+
console.log(` ~ ${m.name} (${m.addon}, ${formatSize(m.expectedSize)})`);
|
|
58
|
+
});
|
|
59
|
+
if (updated.length > 10) {
|
|
60
|
+
console.log(` ... and ${updated.length - 10} more`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
63
|
if (removed.length > 0) {
|
|
64
64
|
console.log(`\n⚠️ ${removed.length} model${removed.length === 1 ? "" : "s"} removed:`);
|
|
65
65
|
removed.slice(0, 5).forEach((m) => {
|
|
@@ -104,8 +104,9 @@ async function updateModels(showDuplicates = false, noDedup = false) {
|
|
|
104
104
|
if (added.length > 0 || removed.length > 0) {
|
|
105
105
|
const historyFile = createHistoryFile(addedWithNames, removed, currentModels, HISTORY_DIR);
|
|
106
106
|
if (historyFile) {
|
|
107
|
+
const { added: trulyAdded, updated, removed: trulyRemoved, } = separateUpdates(addedWithNames, removed);
|
|
107
108
|
console.log(`📜 Created history file → ${historyFile}`);
|
|
108
|
-
console.log(` Added: ${
|
|
109
|
+
console.log(` Added: ${trulyAdded.length}, Updated: ${updated.length}, Removed: ${trulyRemoved.length}`);
|
|
109
110
|
}
|
|
110
111
|
}
|
|
111
112
|
}
|
|
@@ -99,6 +99,8 @@ function generateBaseName(input) {
|
|
|
99
99
|
return generateTtsName(input);
|
|
100
100
|
case "ocr":
|
|
101
101
|
return generateOcrName(input);
|
|
102
|
+
case "parakeet":
|
|
103
|
+
return generateParakeetName(input);
|
|
102
104
|
default:
|
|
103
105
|
return cleanPart(input.filename.replace(/\.\w+$/, ""));
|
|
104
106
|
}
|
|
@@ -312,3 +314,57 @@ function generateOcrName({ filename, tagName, modelName, tagExtra, }) {
|
|
|
312
314
|
const nameParts = [name, language, fileType].filter((p) => p && p !== "");
|
|
313
315
|
return `OCR_${nameParts.map(cleanPart).join("_")}`;
|
|
314
316
|
}
|
|
317
|
+
function generateParakeetName({ filename, lowerPath, quantization, }) {
|
|
318
|
+
const lower = filename.toLowerCase();
|
|
319
|
+
// Detect model variant from registry path
|
|
320
|
+
let variant = "";
|
|
321
|
+
if (lowerPath.includes("parakeet-tdt") || lowerPath.includes("parakeet/")) {
|
|
322
|
+
variant = "TDT";
|
|
323
|
+
}
|
|
324
|
+
else if (lowerPath.includes("parakeet-ctc")) {
|
|
325
|
+
variant = "CTC";
|
|
326
|
+
}
|
|
327
|
+
else if (lowerPath.includes("eou") || lowerPath.includes("parakeet-rs")) {
|
|
328
|
+
variant = "EOU";
|
|
329
|
+
}
|
|
330
|
+
else if (lowerPath.includes("sortformer")) {
|
|
331
|
+
variant = "SORTFORMER";
|
|
332
|
+
}
|
|
333
|
+
// Detect file role from filename
|
|
334
|
+
let fileRole = "";
|
|
335
|
+
if (lower.includes("encoder") && (lower.endsWith(".data") || lower.endsWith(".onnx.data"))) {
|
|
336
|
+
fileRole = "ENCODER_DATA";
|
|
337
|
+
}
|
|
338
|
+
else if (lower.includes("encoder")) {
|
|
339
|
+
fileRole = "ENCODER";
|
|
340
|
+
}
|
|
341
|
+
else if (lower.includes("decoder")) {
|
|
342
|
+
fileRole = "DECODER";
|
|
343
|
+
}
|
|
344
|
+
else if (lower.includes("vocab")) {
|
|
345
|
+
fileRole = "VOCAB";
|
|
346
|
+
}
|
|
347
|
+
else if (lower.includes("tokenizer")) {
|
|
348
|
+
fileRole = "TOKENIZER";
|
|
349
|
+
}
|
|
350
|
+
else if (lower.includes("preprocessor") || lower.includes("nemo")) {
|
|
351
|
+
fileRole = "PREPROCESSOR";
|
|
352
|
+
}
|
|
353
|
+
else if (lower === "config.json") {
|
|
354
|
+
fileRole = "CONFIG";
|
|
355
|
+
}
|
|
356
|
+
else if (lower.endsWith(".onnx.data") || lower.endsWith(".onnx_data")) {
|
|
357
|
+
fileRole = "DATA";
|
|
358
|
+
}
|
|
359
|
+
else if (lower.includes("sortformer")) {
|
|
360
|
+
fileRole = "";
|
|
361
|
+
}
|
|
362
|
+
else if (lower.endsWith(".onnx") || lower.endsWith(".int8.onnx")) {
|
|
363
|
+
fileRole = "";
|
|
364
|
+
}
|
|
365
|
+
else {
|
|
366
|
+
fileRole = cleanPart(filename.replace(/\.\w+$/, ""));
|
|
367
|
+
}
|
|
368
|
+
const nameParts = [variant, fileRole, quantization].filter((p) => p && p !== "");
|
|
369
|
+
return `PARAKEET_${nameParts.map(cleanPart).join("_")}`;
|
|
370
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Accumulates profiling statistics and maintains a bounded buffer of recent events.
|
|
3
|
+
* Uses a ring buffer for O(1) event insertion.
|
|
4
|
+
*/
|
|
5
|
+
import type { ProfilingEvent, AggregatedStats } from "./types";
|
|
6
|
+
export declare function createAggregator(maxRecentEvents?: number): void;
|
|
7
|
+
export declare function recordEvent(event: ProfilingEvent, storeInBuffer?: boolean): void;
|
|
8
|
+
export declare function getAggregates(): Record<string, AggregatedStats>;
|
|
9
|
+
/** Returns events in chronological order (oldest first). */
|
|
10
|
+
export declare function getRecentEvents(): ProfilingEvent[];
|
|
11
|
+
export declare function getEventCount(): number;
|
|
12
|
+
export declare function getDroppedCount(): number;
|
|
13
|
+
export declare function clearAggregator(): void;
|
|
14
|
+
export declare function setMaxRecentEvents(max: number): void;
|
|
15
|
+
//# sourceMappingURL=aggregator.d.ts.map
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Accumulates profiling statistics and maintains a bounded buffer of recent events.
|
|
3
|
+
* Uses a ring buffer for O(1) event insertion.
|
|
4
|
+
*/
|
|
5
|
+
import { getGlobalSingleton } from "../utils/global-singleton.js";
|
|
6
|
+
import { createRingBuffer, ringBufferPush, ringBufferToArray, ringBufferClear, ringBufferResize, ringBufferDroppedCount, } from "./ring-buffer.js";
|
|
7
|
+
const DEFAULT_MAX_RECENT_EVENTS = 1000;
|
|
8
|
+
const AGGREGATOR_STATE_KEY = Symbol.for("@qvac/sdk:profiler-aggregator-state");
|
|
9
|
+
function getAggregatorState() {
|
|
10
|
+
return getGlobalSingleton(AGGREGATOR_STATE_KEY, () => {
|
|
11
|
+
return {
|
|
12
|
+
stats: new Map(),
|
|
13
|
+
eventBuffer: createRingBuffer(DEFAULT_MAX_RECENT_EVENTS),
|
|
14
|
+
};
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
export function createAggregator(maxRecentEvents = DEFAULT_MAX_RECENT_EVENTS) {
|
|
18
|
+
const state = getAggregatorState();
|
|
19
|
+
state.stats = new Map();
|
|
20
|
+
state.eventBuffer = createRingBuffer(maxRecentEvents);
|
|
21
|
+
}
|
|
22
|
+
function recordStats(key, value) {
|
|
23
|
+
const aggregator = getAggregatorState();
|
|
24
|
+
let statsState = aggregator.stats.get(key);
|
|
25
|
+
if (!statsState) {
|
|
26
|
+
statsState = {
|
|
27
|
+
count: 0,
|
|
28
|
+
min: Infinity,
|
|
29
|
+
max: -Infinity,
|
|
30
|
+
sum: 0,
|
|
31
|
+
last: 0,
|
|
32
|
+
};
|
|
33
|
+
aggregator.stats.set(key, statsState);
|
|
34
|
+
}
|
|
35
|
+
statsState.count++;
|
|
36
|
+
statsState.sum += value;
|
|
37
|
+
statsState.last = value;
|
|
38
|
+
if (value < statsState.min)
|
|
39
|
+
statsState.min = value;
|
|
40
|
+
if (value > statsState.max)
|
|
41
|
+
statsState.max = value;
|
|
42
|
+
}
|
|
43
|
+
function getStats(state) {
|
|
44
|
+
return {
|
|
45
|
+
count: state.count,
|
|
46
|
+
min: state.count > 0 ? state.min : 0,
|
|
47
|
+
max: state.count > 0 ? state.max : 0,
|
|
48
|
+
avg: state.count > 0 ? state.sum / state.count : 0,
|
|
49
|
+
sum: state.sum,
|
|
50
|
+
last: state.last,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
export function recordEvent(event, storeInBuffer = true) {
|
|
54
|
+
const state = getAggregatorState();
|
|
55
|
+
if (storeInBuffer) {
|
|
56
|
+
ringBufferPush(state.eventBuffer, event);
|
|
57
|
+
}
|
|
58
|
+
if (event.ms !== undefined) {
|
|
59
|
+
const key = event.phase ? `${event.op}.${event.phase}` : event.op;
|
|
60
|
+
recordStats(key, event.ms);
|
|
61
|
+
}
|
|
62
|
+
if (event.gauges) {
|
|
63
|
+
const baseKey = event.phase ? `${event.op}.${event.phase}` : event.op;
|
|
64
|
+
for (const [gaugeName, value] of Object.entries(event.gauges)) {
|
|
65
|
+
recordStats(`${baseKey}.${gaugeName}`, value);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
export function getAggregates() {
|
|
70
|
+
const state = getAggregatorState();
|
|
71
|
+
const result = {};
|
|
72
|
+
for (const [key, statsState] of state.stats) {
|
|
73
|
+
result[key] = getStats(statsState);
|
|
74
|
+
}
|
|
75
|
+
return result;
|
|
76
|
+
}
|
|
77
|
+
/** Returns events in chronological order (oldest first). */
|
|
78
|
+
export function getRecentEvents() {
|
|
79
|
+
return ringBufferToArray(getAggregatorState().eventBuffer);
|
|
80
|
+
}
|
|
81
|
+
export function getEventCount() {
|
|
82
|
+
const state = getAggregatorState();
|
|
83
|
+
let total = 0;
|
|
84
|
+
for (const statsState of state.stats.values()) {
|
|
85
|
+
total += statsState.count;
|
|
86
|
+
}
|
|
87
|
+
return total;
|
|
88
|
+
}
|
|
89
|
+
export function getDroppedCount() {
|
|
90
|
+
return ringBufferDroppedCount(getAggregatorState().eventBuffer);
|
|
91
|
+
}
|
|
92
|
+
export function clearAggregator() {
|
|
93
|
+
const state = getAggregatorState();
|
|
94
|
+
state.stats.clear();
|
|
95
|
+
ringBufferClear(state.eventBuffer);
|
|
96
|
+
}
|
|
97
|
+
export function setMaxRecentEvents(max) {
|
|
98
|
+
const state = getAggregatorState();
|
|
99
|
+
state.eventBuffer = ringBufferResize(state.eventBuffer, max);
|
|
100
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime-safe monotonic clock for profiling.
|
|
3
|
+
* Priority: performance.now > process.hrtime > Date.now
|
|
4
|
+
*/
|
|
5
|
+
export type ClockSource = "performance" | "hrtime" | "date";
|
|
6
|
+
export declare function getClockSource(): ClockSource;
|
|
7
|
+
export declare function isMonotonic(): boolean;
|
|
8
|
+
export declare function nowMs(): number;
|
|
9
|
+
export declare function measureAsync<T>(fn: () => Promise<T>): Promise<[T, number]>;
|
|
10
|
+
export declare function measureSync<T>(fn: () => T): [T, number];
|
|
11
|
+
export declare function generateProfileId(): string;
|
|
12
|
+
//# sourceMappingURL=clock.d.ts.map
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime-safe monotonic clock for profiling.
|
|
3
|
+
* Priority: performance.now > process.hrtime > Date.now
|
|
4
|
+
*/
|
|
5
|
+
let clockSource;
|
|
6
|
+
let nowMsImpl;
|
|
7
|
+
// Detect and cache the best available clock source at module load
|
|
8
|
+
if (typeof globalThis !== "undefined" &&
|
|
9
|
+
typeof globalThis.performance !== "undefined" &&
|
|
10
|
+
typeof globalThis.performance.now === "function") {
|
|
11
|
+
clockSource = "performance";
|
|
12
|
+
const perfNow = globalThis.performance.now.bind(globalThis.performance);
|
|
13
|
+
nowMsImpl = () => perfNow();
|
|
14
|
+
}
|
|
15
|
+
else if (typeof process !== "undefined" &&
|
|
16
|
+
typeof process.hrtime === "function" &&
|
|
17
|
+
typeof process.hrtime.bigint === "function") {
|
|
18
|
+
clockSource = "hrtime";
|
|
19
|
+
const hrtime = process.hrtime.bigint.bind(process.hrtime);
|
|
20
|
+
const startNs = hrtime();
|
|
21
|
+
nowMsImpl = () => Number(hrtime() - startNs) / 1_000_000;
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
clockSource = "date";
|
|
25
|
+
const startMs = Date.now();
|
|
26
|
+
nowMsImpl = () => Date.now() - startMs;
|
|
27
|
+
}
|
|
28
|
+
export function getClockSource() {
|
|
29
|
+
return clockSource;
|
|
30
|
+
}
|
|
31
|
+
export function isMonotonic() {
|
|
32
|
+
return clockSource === "performance" || clockSource === "hrtime";
|
|
33
|
+
}
|
|
34
|
+
export function nowMs() {
|
|
35
|
+
return nowMsImpl();
|
|
36
|
+
}
|
|
37
|
+
export async function measureAsync(fn) {
|
|
38
|
+
const start = nowMs();
|
|
39
|
+
const result = await fn();
|
|
40
|
+
return [result, nowMs() - start];
|
|
41
|
+
}
|
|
42
|
+
export function measureSync(fn) {
|
|
43
|
+
const start = nowMs();
|
|
44
|
+
const result = fn();
|
|
45
|
+
return [result, nowMs() - start];
|
|
46
|
+
}
|
|
47
|
+
export function generateProfileId() {
|
|
48
|
+
const timestamp = Date.now().toString(36);
|
|
49
|
+
const random = Math.random().toString(36).substring(2, 8);
|
|
50
|
+
return `${timestamp}-${random}`;
|
|
51
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Central state management for profiling enablement, configuration, and recording.
|
|
3
|
+
*
|
|
4
|
+
* Precedence (highest to lowest):
|
|
5
|
+
* 1. Per-call override
|
|
6
|
+
* 2. Runtime API (enable/disable)
|
|
7
|
+
* 3. Disabled default
|
|
8
|
+
*/
|
|
9
|
+
import type { ProfilerMode, PerCallProfiling } from "../schemas/index";
|
|
10
|
+
import type { ProfilerRuntimeOptions, ProfilingEvent, AggregatedStats } from "./types";
|
|
11
|
+
export interface ResolvedProfilerConfig {
|
|
12
|
+
enabled: boolean;
|
|
13
|
+
mode: ProfilerMode;
|
|
14
|
+
includeServerBreakdown: boolean;
|
|
15
|
+
operationFilters: string[];
|
|
16
|
+
maxRecentEvents: number;
|
|
17
|
+
}
|
|
18
|
+
type RecordCallback = (event: ProfilingEvent) => void;
|
|
19
|
+
export declare function enable(options?: ProfilerRuntimeOptions): void;
|
|
20
|
+
export declare function disable(): void;
|
|
21
|
+
export declare function isEnabled(): boolean;
|
|
22
|
+
export declare function getEffectiveConfig(): ResolvedProfilerConfig;
|
|
23
|
+
export declare function shouldProfile(operation: string, perCallOptions?: PerCallProfiling): boolean;
|
|
24
|
+
export declare function shouldIncludeServerBreakdown(perCallOptions?: PerCallProfiling): boolean;
|
|
25
|
+
export declare function generateId(): string;
|
|
26
|
+
export declare function record(event: ProfilingEvent): void;
|
|
27
|
+
/** Returns unsubscribe function. */
|
|
28
|
+
export declare function onRecord(callback: RecordCallback): () => void;
|
|
29
|
+
export declare function getAggregates(): Record<string, AggregatedStats>;
|
|
30
|
+
export declare function getRecentEvents(): ProfilingEvent[];
|
|
31
|
+
export declare function clear(): void;
|
|
32
|
+
export {};
|
|
33
|
+
//# sourceMappingURL=controller.d.ts.map
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Central state management for profiling enablement, configuration, and recording.
|
|
3
|
+
*
|
|
4
|
+
* Precedence (highest to lowest):
|
|
5
|
+
* 1. Per-call override
|
|
6
|
+
* 2. Runtime API (enable/disable)
|
|
7
|
+
* 3. Disabled default
|
|
8
|
+
*/
|
|
9
|
+
import { getGlobalSingleton } from "../utils/global-singleton.js";
|
|
10
|
+
import { createAggregator, recordEvent as aggregatorRecord, getAggregates as aggregatorGetAggregates, getRecentEvents as aggregatorGetRecentEvents, clearAggregator, setMaxRecentEvents, } from "./aggregator.js";
|
|
11
|
+
import { nowMs, generateProfileId } from "./clock.js";
|
|
12
|
+
const DEFAULT_CONFIG = {
|
|
13
|
+
enabled: false,
|
|
14
|
+
mode: "summary",
|
|
15
|
+
includeServerBreakdown: false,
|
|
16
|
+
operationFilters: [],
|
|
17
|
+
maxRecentEvents: 1000,
|
|
18
|
+
};
|
|
19
|
+
const CONTROLLER_STATE_KEY = Symbol.for("@qvac/sdk:profiler-controller-state");
|
|
20
|
+
function getControllerState() {
|
|
21
|
+
const state = getGlobalSingleton(CONTROLLER_STATE_KEY, () => {
|
|
22
|
+
return {
|
|
23
|
+
runtimeOverride: undefined,
|
|
24
|
+
runtimeOptions: {},
|
|
25
|
+
onRecordCallbacks: [],
|
|
26
|
+
initialized: false,
|
|
27
|
+
};
|
|
28
|
+
});
|
|
29
|
+
if (!state.initialized) {
|
|
30
|
+
createAggregator(DEFAULT_CONFIG.maxRecentEvents);
|
|
31
|
+
state.initialized = true;
|
|
32
|
+
}
|
|
33
|
+
return state;
|
|
34
|
+
}
|
|
35
|
+
export function enable(options) {
|
|
36
|
+
const state = getControllerState();
|
|
37
|
+
state.runtimeOverride = true;
|
|
38
|
+
state.runtimeOptions = options ? { ...options } : {};
|
|
39
|
+
clearAggregator();
|
|
40
|
+
setMaxRecentEvents(DEFAULT_CONFIG.maxRecentEvents);
|
|
41
|
+
}
|
|
42
|
+
export function disable() {
|
|
43
|
+
const state = getControllerState();
|
|
44
|
+
state.runtimeOverride = false;
|
|
45
|
+
state.runtimeOptions = {};
|
|
46
|
+
setMaxRecentEvents(DEFAULT_CONFIG.maxRecentEvents);
|
|
47
|
+
}
|
|
48
|
+
export function isEnabled() {
|
|
49
|
+
const state = getControllerState();
|
|
50
|
+
return state.runtimeOverride ?? false;
|
|
51
|
+
}
|
|
52
|
+
export function getEffectiveConfig() {
|
|
53
|
+
const state = getControllerState();
|
|
54
|
+
return {
|
|
55
|
+
enabled: isEnabled(),
|
|
56
|
+
mode: state.runtimeOptions.mode ?? DEFAULT_CONFIG.mode,
|
|
57
|
+
includeServerBreakdown: state.runtimeOptions.includeServerBreakdown ??
|
|
58
|
+
DEFAULT_CONFIG.includeServerBreakdown,
|
|
59
|
+
operationFilters: [
|
|
60
|
+
...(state.runtimeOptions.operationFilters ?? DEFAULT_CONFIG.operationFilters),
|
|
61
|
+
],
|
|
62
|
+
maxRecentEvents: DEFAULT_CONFIG.maxRecentEvents,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
export function shouldProfile(operation, perCallOptions) {
|
|
66
|
+
if (perCallOptions?.enabled !== undefined) {
|
|
67
|
+
return perCallOptions.enabled;
|
|
68
|
+
}
|
|
69
|
+
if (!isEnabled()) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
const config = getEffectiveConfig();
|
|
73
|
+
if (config.operationFilters.length > 0) {
|
|
74
|
+
return config.operationFilters.includes(operation);
|
|
75
|
+
}
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
export function shouldIncludeServerBreakdown(perCallOptions) {
|
|
79
|
+
if (perCallOptions?.includeServerBreakdown !== undefined) {
|
|
80
|
+
return perCallOptions.includeServerBreakdown;
|
|
81
|
+
}
|
|
82
|
+
return getEffectiveConfig().includeServerBreakdown;
|
|
83
|
+
}
|
|
84
|
+
export function generateId() {
|
|
85
|
+
return generateProfileId();
|
|
86
|
+
}
|
|
87
|
+
export function record(event) {
|
|
88
|
+
const state = getControllerState();
|
|
89
|
+
let eventWithTs = event;
|
|
90
|
+
if (event.ts === undefined) {
|
|
91
|
+
eventWithTs = { ...event, ts: nowMs() };
|
|
92
|
+
}
|
|
93
|
+
const storeInBuffer = getEffectiveConfig().mode === "verbose";
|
|
94
|
+
aggregatorRecord(eventWithTs, storeInBuffer);
|
|
95
|
+
for (const cb of state.onRecordCallbacks) {
|
|
96
|
+
try {
|
|
97
|
+
cb(eventWithTs);
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
// Callback errors should not break profiling
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/** Returns unsubscribe function. */
|
|
105
|
+
export function onRecord(callback) {
|
|
106
|
+
const state = getControllerState();
|
|
107
|
+
state.onRecordCallbacks.push(callback);
|
|
108
|
+
return () => {
|
|
109
|
+
const idx = state.onRecordCallbacks.indexOf(callback);
|
|
110
|
+
if (idx >= 0) {
|
|
111
|
+
state.onRecordCallbacks.splice(idx, 1);
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
export function getAggregates() {
|
|
116
|
+
return aggregatorGetAggregates();
|
|
117
|
+
}
|
|
118
|
+
export function getRecentEvents() {
|
|
119
|
+
return aggregatorGetRecentEvents();
|
|
120
|
+
}
|
|
121
|
+
export function clear() {
|
|
122
|
+
clearAggregator();
|
|
123
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helpers to inject/extract __profiling metadata in RPC payloads.
|
|
3
|
+
*/
|
|
4
|
+
import { type ProfilingRequestMeta, type ProfilingResponseMeta } from "../schemas/index";
|
|
5
|
+
export declare function createProfilingMeta(profileId: string, includeServerBreakdown: boolean): ProfilingRequestMeta;
|
|
6
|
+
export declare function createProfilingDisabledMeta(): ProfilingRequestMeta;
|
|
7
|
+
export declare function injectProfilingMetaIntoObject(obj: Record<string, unknown>, meta: ProfilingRequestMeta): Record<string, unknown>;
|
|
8
|
+
export declare function extractProfilingMeta(payload: unknown): ProfilingResponseMeta | undefined;
|
|
9
|
+
export declare function stripProfilingMeta<T extends object>(payload: T): T;
|
|
10
|
+
//# sourceMappingURL=envelope.d.ts.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helpers to inject/extract __profiling metadata in RPC payloads.
|
|
3
|
+
*/
|
|
4
|
+
import { PROFILING_KEY, } from "../schemas/index.js";
|
|
5
|
+
export function createProfilingMeta(profileId, includeServerBreakdown) {
|
|
6
|
+
return {
|
|
7
|
+
enabled: true,
|
|
8
|
+
id: profileId,
|
|
9
|
+
includeServer: includeServerBreakdown,
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export function createProfilingDisabledMeta() {
|
|
13
|
+
return { enabled: false };
|
|
14
|
+
}
|
|
15
|
+
export function injectProfilingMetaIntoObject(obj, meta) {
|
|
16
|
+
return { ...obj, [PROFILING_KEY]: meta };
|
|
17
|
+
}
|
|
18
|
+
export function extractProfilingMeta(payload) {
|
|
19
|
+
if (typeof payload === "object" &&
|
|
20
|
+
payload !== null &&
|
|
21
|
+
PROFILING_KEY in payload) {
|
|
22
|
+
const meta = payload[PROFILING_KEY];
|
|
23
|
+
if (typeof meta === "object" && meta !== null) {
|
|
24
|
+
return meta;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
export function stripProfilingMeta(payload) {
|
|
30
|
+
if (PROFILING_KEY in payload) {
|
|
31
|
+
const { [PROFILING_KEY]: _unused, ...rest } = payload;
|
|
32
|
+
void _unused;
|
|
33
|
+
return rest;
|
|
34
|
+
}
|
|
35
|
+
return payload;
|
|
36
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ProfilingEventKind } from "./types";
|
|
2
|
+
import type { ServerBreakdown, DelegationBreakdown } from "../schemas/index";
|
|
3
|
+
export interface BaseTimings {
|
|
4
|
+
profileId: string;
|
|
5
|
+
requestType: string;
|
|
6
|
+
requestStart: number;
|
|
7
|
+
}
|
|
8
|
+
export interface BaseEvent {
|
|
9
|
+
ts: number;
|
|
10
|
+
op: string;
|
|
11
|
+
kind: ProfilingEventKind;
|
|
12
|
+
profileId: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function recordPhase(base: BaseEvent, phase: string, ms?: number, extra?: {
|
|
15
|
+
count?: number;
|
|
16
|
+
}): void;
|
|
17
|
+
export declare function recordFailure(base: BaseEvent, startTime: number, error: unknown): void;
|
|
18
|
+
export declare function recordServerBreakdownPhases(base: BaseEvent, server: ServerBreakdown, prefix?: string): void;
|
|
19
|
+
export declare function recordDelegationBreakdownPhases(base: BaseEvent, delegation: DelegationBreakdown, prefix?: string): void;
|
|
20
|
+
//# sourceMappingURL=events.d.ts.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { nowMs } from "./clock.js";
|
|
2
|
+
import { record } from "./controller.js";
|
|
3
|
+
export function recordPhase(base, phase, ms, extra) {
|
|
4
|
+
if (ms === undefined)
|
|
5
|
+
return;
|
|
6
|
+
record({ ...base, phase, ms, ...extra });
|
|
7
|
+
}
|
|
8
|
+
export function recordFailure(base, startTime, error) {
|
|
9
|
+
const now = nowMs();
|
|
10
|
+
record({
|
|
11
|
+
...base,
|
|
12
|
+
ts: now,
|
|
13
|
+
phase: "failed",
|
|
14
|
+
ms: now - startTime,
|
|
15
|
+
tags: {
|
|
16
|
+
error: error instanceof Error ? error.name : "Unknown",
|
|
17
|
+
message: error instanceof Error
|
|
18
|
+
? error.message.slice(0, 100)
|
|
19
|
+
: String(error).slice(0, 100),
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
export function recordServerBreakdownPhases(base, server, prefix = "server") {
|
|
24
|
+
recordPhase(base, `${prefix}.request.jsonParse`, server.requestJsonParseMs);
|
|
25
|
+
recordPhase(base, `${prefix}.request.zodValidation`, server.requestZodValidationMs);
|
|
26
|
+
recordPhase(base, `${prefix}.handlerExecution`, server.handlerExecutionMs);
|
|
27
|
+
recordPhase(base, `${prefix}.response.zodValidation`, server.responseZodValidationMs);
|
|
28
|
+
recordPhase(base, `${prefix}.response.stringify`, server.responseStringifyMs);
|
|
29
|
+
recordPhase(base, `${prefix}.totalServerTime`, server.totalServerMs);
|
|
30
|
+
}
|
|
31
|
+
export function recordDelegationBreakdownPhases(base, delegation, prefix = "delegation") {
|
|
32
|
+
recordPhase(base, `${prefix}.connection`, delegation.connectionMs);
|
|
33
|
+
recordPhase(base, `${prefix}.request.stringify`, delegation.requestStringifyMs);
|
|
34
|
+
recordPhase(base, `${prefix}.serverWait`, delegation.serverWaitMs);
|
|
35
|
+
recordPhase(base, `${prefix}.response.jsonParse`, delegation.responseJsonParseMs);
|
|
36
|
+
recordPhase(base, `${prefix}.totalDelegationTime`, delegation.totalDelegationMs);
|
|
37
|
+
}
|