@qvac/sdk 0.11.0 → 0.12.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 +1427 -39
- package/README.md +2 -0
- package/dist/client/api/classify.d.ts +23 -0
- package/dist/client/api/classify.js +43 -0
- package/dist/client/api/get-model-info.d.ts +1 -1
- package/dist/client/api/index.d.ts +4 -0
- package/dist/client/api/index.js +4 -0
- package/dist/client/api/load-model.js +24 -1
- package/dist/client/api/transcribe.d.ts +3 -0
- package/dist/client/api/transcribe.js +13 -2
- package/dist/client/api/video.d.ts +64 -0
- package/dist/client/api/video.js +147 -0
- package/dist/client/api/vla-helpers.d.ts +45 -0
- package/dist/client/api/vla-helpers.js +130 -0
- package/dist/client/api/vla.d.ts +65 -0
- package/dist/client/api/vla.js +109 -0
- package/dist/client/config-loader/resolve-config.node.d.ts +16 -0
- package/dist/client/config-loader/resolve-config.node.js +77 -23
- package/dist/client/plugins-factory.d.ts +8 -0
- package/dist/client/plugins-factory.js +10 -0
- package/dist/client/rpc/bare-client.js +62 -66
- package/dist/client/rpc/ensure-worker-ready.d.ts +9 -0
- package/dist/client/rpc/ensure-worker-ready.js +17 -0
- package/dist/client/rpc/node-rpc-client.js +4 -1
- package/dist/client/rpc/rpc-error.js +14 -1
- package/dist/commands/bundle/bare-pack.d.ts +13 -0
- package/dist/commands/bundle/bare-pack.js +54 -0
- package/dist/commands/bundle/constants.d.ts +7 -0
- package/dist/commands/bundle/constants.js +23 -0
- package/dist/commands/bundle/entry-gen.d.ts +2 -0
- package/dist/commands/bundle/entry-gen.js +48 -0
- package/dist/commands/bundle/index.d.ts +20 -0
- package/dist/commands/bundle/index.js +141 -0
- package/dist/commands/bundle/manifest.d.ts +21 -0
- package/dist/commands/bundle/manifest.js +193 -0
- package/dist/commands/bundle/plugins.d.ts +9 -0
- package/dist/commands/bundle/plugins.js +51 -0
- package/dist/commands/index.d.ts +5 -0
- package/dist/commands/index.js +2 -0
- package/dist/commands/verify/abi.d.ts +52 -0
- package/dist/commands/verify/abi.js +125 -0
- package/dist/commands/verify/addon-source.d.ts +43 -0
- package/dist/commands/verify/addon-source.js +75 -0
- package/dist/commands/verify/bundle-source.d.ts +12 -0
- package/dist/commands/verify/bundle-source.js +53 -0
- package/dist/commands/verify/index.d.ts +59 -0
- package/dist/commands/verify/index.js +371 -0
- package/dist/commands/verify/node-modules-source.d.ts +11 -0
- package/dist/commands/verify/node-modules-source.js +76 -0
- package/dist/commands/verify/prebuilds.d.ts +15 -0
- package/dist/commands/verify/prebuilds.js +39 -0
- package/dist/examples/classification/classify-image.d.ts +2 -0
- package/dist/examples/classification/classify-image.js +23 -0
- package/dist/examples/diffusion-txt2vid.d.ts +2 -0
- package/dist/examples/diffusion-txt2vid.js +81 -0
- package/dist/examples/plugins.js +3 -7
- package/dist/examples/tools/llamacpp-tools-gemma4.js +2 -5
- package/dist/examples/tools/llamacpp-tools-qwen35.js +2 -3
- package/dist/examples/transcription/parakeet-ctc-filesystem.js +18 -12
- package/dist/examples/transcription/parakeet-microphone-record.js +7 -12
- package/dist/examples/transcription/parakeet-microphone-stream.d.ts +2 -0
- package/dist/examples/transcription/parakeet-microphone-stream.js +79 -0
- package/dist/examples/transcription/parakeet-sortformer-streaming.d.ts +2 -0
- package/dist/examples/transcription/parakeet-sortformer-streaming.js +121 -0
- package/dist/examples/transcription/parakeet-sortformer.js +58 -55
- package/dist/examples/transcription/parakeet-tdt-filesystem.js +18 -15
- package/dist/examples/transcription/whispercpp-microphone-conversation.js +6 -1
- package/dist/examples/tts/chatterbox.js +7 -16
- package/dist/examples/tts/llm-to-tts-streaming.js +3 -10
- package/dist/examples/tts/supertonic-multilingual.js +4 -12
- package/dist/examples/tts/supertonic.js +5 -12
- package/dist/examples/vla-smolvla.d.ts +2 -0
- package/dist/examples/vla-smolvla.js +75 -0
- package/dist/examples/voice-assistant/voice-assistant.js +3 -10
- package/dist/expo/plugins/find-in-ancestor-node-modules.d.ts +14 -0
- package/dist/expo/plugins/find-in-ancestor-node-modules.js +24 -0
- package/dist/expo/plugins/get-project-root.d.ts +22 -0
- package/dist/expo/plugins/get-project-root.js +23 -0
- package/dist/expo/plugins/index.d.ts +4 -0
- package/dist/expo/plugins/index.js +4 -0
- package/dist/expo/plugins/resolve-sdk-package-dir.d.ts +9 -2
- package/dist/expo/plugins/resolve-sdk-package-dir.js +38 -11
- package/dist/expo/plugins/withDeviceInfo.js +2 -1
- package/dist/expo/plugins/withMobileBundle.d.ts +2 -17
- package/dist/expo/plugins/withMobileBundle.js +31 -85
- package/dist/index.d.ts +4 -3
- package/dist/index.js +4 -3
- package/dist/models/registry/models.d.ts +3711 -368
- package/dist/models/registry/models.js +7066 -3562
- package/dist/models/update-models/naming.js +22 -8
- package/dist/pear/pre.js +6 -2
- package/dist/schemas/cancel.d.ts +5 -0
- package/dist/schemas/cancel.js +1 -0
- package/dist/schemas/classification.d.ts +53 -0
- package/dist/schemas/classification.js +33 -0
- package/dist/schemas/common.d.ts +1001 -1739
- package/dist/schemas/common.js +6 -1
- package/dist/schemas/completion-event.d.ts +3 -0
- package/dist/schemas/completion-event.js +1 -0
- package/dist/schemas/completion-stream.d.ts +1 -0
- package/dist/schemas/download-asset.d.ts +13 -3
- package/dist/schemas/engine-addon-map.d.ts +3 -0
- package/dist/schemas/engine-addon-map.js +18 -5
- package/dist/schemas/get-model-info.d.ts +4 -0
- package/dist/schemas/get-model-info.js +2 -0
- package/dist/schemas/index.d.ts +3 -0
- package/dist/schemas/index.js +3 -0
- package/dist/schemas/llamacpp-config.d.ts +12 -2
- package/dist/schemas/load-model.d.ts +6152 -10764
- package/dist/schemas/load-model.js +75 -7
- package/dist/schemas/model-src-utils.d.ts +22 -2
- package/dist/schemas/model-types.d.ts +46 -6
- package/dist/schemas/model-types.js +28 -5
- package/dist/schemas/ocr.d.ts +5 -0
- package/dist/schemas/plugin.d.ts +20 -5
- package/dist/schemas/plugin.js +21 -4
- package/dist/schemas/registry.d.ts +44 -0
- package/dist/schemas/registry.js +5 -0
- package/dist/schemas/reload-config.d.ts +22 -2
- package/dist/schemas/sdcpp-config.d.ts +316 -1
- package/dist/schemas/sdcpp-config.js +232 -33
- package/dist/schemas/sdk-config.d.ts +654 -1324
- package/dist/schemas/sdk-config.js +16 -1
- package/dist/schemas/sdk-errors-client.d.ts +5 -0
- package/dist/schemas/sdk-errors-client.js +26 -1
- package/dist/schemas/sdk-errors-server.d.ts +3 -1
- package/dist/schemas/sdk-errors-server.js +20 -5
- package/dist/schemas/text-to-speech.d.ts +79 -696
- package/dist/schemas/text-to-speech.js +46 -19
- package/dist/schemas/transcription-config.d.ts +37 -226
- package/dist/schemas/transcription-config.js +76 -15
- package/dist/schemas/transcription.d.ts +63 -11
- package/dist/schemas/transcription.js +56 -2
- package/dist/schemas/translation-config.d.ts +60 -10
- package/dist/schemas/vla.d.ts +87 -0
- package/dist/schemas/vla.js +108 -0
- package/dist/scripts/run-unit-tests.js +8 -2
- package/dist/server/bare/ops/transcribe.d.ts +2 -1
- package/dist/server/bare/ops/transcribe.js +59 -34
- package/dist/server/bare/plugins/ggml-classification/ops/classify.d.ts +6 -0
- package/dist/server/bare/plugins/ggml-classification/ops/classify.js +30 -0
- package/dist/server/bare/plugins/ggml-classification/plugin.d.ts +32 -0
- package/dist/server/bare/plugins/ggml-classification/plugin.js +55 -0
- package/dist/server/bare/plugins/ggml-vla/ops/vla-hparams.d.ts +3 -0
- package/dist/server/bare/plugins/ggml-vla/ops/vla-hparams.js +12 -0
- package/dist/server/bare/plugins/ggml-vla/ops/vla-run.d.ts +3 -0
- package/dist/server/bare/plugins/ggml-vla/ops/vla-run.js +75 -0
- package/dist/server/bare/plugins/ggml-vla/plugin.d.ts +54 -0
- package/dist/server/bare/plugins/ggml-vla/plugin.js +57 -0
- package/dist/server/bare/plugins/index.d.ts +3 -1
- package/dist/server/bare/plugins/index.js +3 -1
- package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stream.js +3 -0
- package/dist/server/bare/plugins/llamacpp-completion/ops/context-overflow.d.ts +29 -0
- package/dist/server/bare/plugins/llamacpp-completion/ops/context-overflow.js +65 -0
- package/dist/server/bare/plugins/llamacpp-completion/plugin.d.ts +6 -0
- package/dist/server/bare/plugins/llamacpp-completion/plugin.js +26 -0
- package/dist/server/bare/plugins/nmtcpp-translation/plugin.d.ts +25 -0
- package/dist/server/bare/plugins/onnx-ocr/plugin.d.ts +5 -0
- package/dist/server/bare/plugins/parakeet-transcription/plugin.d.ts +67 -246
- package/dist/server/bare/plugins/parakeet-transcription/plugin.js +66 -97
- package/dist/server/bare/plugins/sdcpp-generation/ops/video.d.ts +3 -0
- package/dist/server/bare/plugins/sdcpp-generation/ops/video.js +199 -0
- package/dist/server/bare/plugins/sdcpp-generation/plugin.d.ts +200 -2
- package/dist/server/bare/plugins/sdcpp-generation/plugin.js +61 -8
- package/dist/server/bare/plugins/{onnx-tts → tts-ggml}/ops/text-to-speech-stream.js +2 -15
- package/dist/server/bare/plugins/{onnx-tts → tts-ggml}/ops/text-to-speech.js +2 -1
- package/dist/server/bare/plugins/tts-ggml/plugin.d.ts +75 -0
- package/dist/server/bare/plugins/tts-ggml/plugin.js +189 -0
- package/dist/server/bare/plugins/whispercpp-transcription/plugin.d.ts +29 -4
- package/dist/server/bare/plugins/whispercpp-transcription/plugin.js +12 -1
- package/dist/server/bare/registry/model-config-utils.js +7 -0
- package/dist/server/bare/runtime/request-context.d.ts +1 -1
- package/dist/server/bare/runtime-lifecycle.js +9 -9
- package/dist/server/bare/types/addon-responses.d.ts +1 -0
- package/dist/server/env.js +4 -1
- package/dist/server/plugins/index.d.ts +1 -1
- package/dist/server/plugins/index.js +1 -1
- package/dist/server/plugins/registry.d.ts +1 -0
- package/dist/server/plugins/registry.js +5 -0
- package/dist/server/rpc/handler-registry.js +4 -0
- package/dist/server/rpc/handler-selection.d.ts +9 -0
- package/dist/server/rpc/handler-selection.js +14 -0
- package/dist/server/rpc/handler-utils.js +5 -13
- package/dist/server/rpc/handlers/classify.d.ts +3 -0
- package/dist/server/rpc/handlers/classify.js +4 -0
- package/dist/server/rpc/handlers/index.d.ts +2 -0
- package/dist/server/rpc/handlers/index.js +2 -0
- package/dist/server/rpc/handlers/load-model/handler.js +4 -1
- package/dist/server/rpc/handlers/load-model/resolve.js +9 -0
- package/dist/server/rpc/handlers/video-stream.d.ts +3 -0
- package/dist/server/rpc/handlers/video-stream.js +4 -0
- package/dist/server/rpc/profiling/operation-metrics.js +23 -0
- package/dist/server/utils/config-transform.js +1 -1
- package/dist/server/worker.js +14 -11
- package/dist/utils/errors-client.d.ts +15 -0
- package/dist/utils/errors-client.js +26 -0
- package/dist/utils/errors-server.d.ts +30 -2
- package/dist/utils/errors-server.js +51 -3
- package/package.json +66 -80
- package/dist/server/bare/plugins/onnx-tts/plugin.d.ts +0 -490
- package/dist/server/bare/plugins/onnx-tts/plugin.js +0 -272
- package/dist/server/bare/plugins/onnx-tts/wav-helper.d.ts +0 -14
- package/dist/server/bare/plugins/onnx-tts/wav-helper.js +0 -107
- /package/dist/server/bare/plugins/{onnx-tts → tts-ggml}/ops/text-to-speech-stream.d.ts +0 -0
- /package/dist/server/bare/plugins/{onnx-tts → tts-ggml}/ops/text-to-speech.d.ts +0 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import ttsAddonLogging from "@qvac/tts-ggml/addonLogging.js";
|
|
2
|
+
import TTSGgml from "@qvac/tts-ggml";
|
|
3
|
+
import { definePlugin, defineHandler, defineDuplexHandler, ttsRequestSchema, ttsResponseSchema, textToSpeechStreamRequestSchema, textToSpeechStreamResponseSchema, ModelType, ttsConfigSchema, ADDON_TTS, LEGACY_TTS_ONNX_MODEL_CONFIG_FIELDS, } from "../../../../schemas/index.js";
|
|
4
|
+
import { createStreamLogger, registerAddonLogger } from "../../../../logging/index.js";
|
|
5
|
+
import { TtsArtifactsRequiredError, LegacyTtsModelDeprecatedError, } from "../../../../utils/errors-server.js";
|
|
6
|
+
import { textToSpeech } from "./ops/text-to-speech.js";
|
|
7
|
+
import { textToSpeechStream } from "./ops/text-to-speech-stream.js";
|
|
8
|
+
import { attachModelExecutionMs } from "../../../../profiling/model-execution.js";
|
|
9
|
+
function rejectLegacyOnnxFields(cfg) {
|
|
10
|
+
const record = cfg;
|
|
11
|
+
const legacyFields = LEGACY_TTS_ONNX_MODEL_CONFIG_FIELDS.filter((name) => record[name] !== undefined);
|
|
12
|
+
if (legacyFields.length > 0) {
|
|
13
|
+
throw new LegacyTtsModelDeprecatedError(legacyFields);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
async function resolveChatterboxConfig(config, ctx) {
|
|
17
|
+
rejectLegacyOnnxFields(config);
|
|
18
|
+
const { s3genModelSrc, referenceAudioSrc, ...runtime } = config;
|
|
19
|
+
if (!s3genModelSrc) {
|
|
20
|
+
throw new TtsArtifactsRequiredError();
|
|
21
|
+
}
|
|
22
|
+
const resolve = ctx.resolveModelPath;
|
|
23
|
+
const [s3genPath, referenceAudioPath] = await Promise.all([
|
|
24
|
+
resolve(s3genModelSrc),
|
|
25
|
+
referenceAudioSrc ? resolve(referenceAudioSrc) : Promise.resolve(undefined),
|
|
26
|
+
]);
|
|
27
|
+
return {
|
|
28
|
+
config: runtime,
|
|
29
|
+
artifacts: {
|
|
30
|
+
s3genPath,
|
|
31
|
+
...(referenceAudioPath ? { referenceAudioPath } : {}),
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function resolveSupertonicConfig(config) {
|
|
36
|
+
rejectLegacyOnnxFields(config);
|
|
37
|
+
return Promise.resolve({ config });
|
|
38
|
+
}
|
|
39
|
+
function createChatterboxModel(modelId, config, params, artifacts) {
|
|
40
|
+
const t3Model = params.modelPath;
|
|
41
|
+
const s3genModel = artifacts["s3genPath"];
|
|
42
|
+
const referenceAudioPath = artifacts["referenceAudioPath"];
|
|
43
|
+
if (!t3Model || !s3genModel) {
|
|
44
|
+
throw new TtsArtifactsRequiredError();
|
|
45
|
+
}
|
|
46
|
+
const logger = createStreamLogger(modelId, ModelType.ttsGgml);
|
|
47
|
+
registerAddonLogger(modelId, ModelType.ttsGgml, logger);
|
|
48
|
+
const model = new TTSGgml({
|
|
49
|
+
engine: TTSGgml.ENGINE_CHATTERBOX,
|
|
50
|
+
files: { t3Model, s3genModel },
|
|
51
|
+
...(referenceAudioPath ? { referenceAudio: referenceAudioPath } : {}),
|
|
52
|
+
config: {
|
|
53
|
+
language: config.language ?? "en",
|
|
54
|
+
...(config.useGPU !== undefined ? { useGPU: config.useGPU } : {}),
|
|
55
|
+
},
|
|
56
|
+
logger,
|
|
57
|
+
opts: { stats: true },
|
|
58
|
+
exclusiveRun: true,
|
|
59
|
+
});
|
|
60
|
+
return { model };
|
|
61
|
+
}
|
|
62
|
+
function createSupertonicModel(modelId, config, params) {
|
|
63
|
+
const supertonicModel = params.modelPath;
|
|
64
|
+
if (!supertonicModel) {
|
|
65
|
+
throw new TtsArtifactsRequiredError();
|
|
66
|
+
}
|
|
67
|
+
const logger = createStreamLogger(modelId, ModelType.ttsGgml);
|
|
68
|
+
registerAddonLogger(modelId, ModelType.ttsGgml, logger);
|
|
69
|
+
const model = new TTSGgml({
|
|
70
|
+
engine: TTSGgml.ENGINE_SUPERTONIC,
|
|
71
|
+
files: { supertonicModel },
|
|
72
|
+
voice: config.voice ?? "F1",
|
|
73
|
+
...(config.ttsSpeed !== undefined ? { speed: config.ttsSpeed } : {}),
|
|
74
|
+
...(config.ttsNumInferenceSteps !== undefined
|
|
75
|
+
? { numInferenceSteps: config.ttsNumInferenceSteps }
|
|
76
|
+
: {}),
|
|
77
|
+
config: {
|
|
78
|
+
language: config.language ?? "en",
|
|
79
|
+
useGPU: config.useGPU ?? false,
|
|
80
|
+
},
|
|
81
|
+
logger,
|
|
82
|
+
opts: { stats: true },
|
|
83
|
+
exclusiveRun: true,
|
|
84
|
+
});
|
|
85
|
+
return { model };
|
|
86
|
+
}
|
|
87
|
+
export const ttsPlugin = definePlugin({
|
|
88
|
+
modelType: ModelType.ttsGgml,
|
|
89
|
+
displayName: "TTS (GGML)",
|
|
90
|
+
addonPackage: ADDON_TTS,
|
|
91
|
+
loadConfigSchema: ttsConfigSchema,
|
|
92
|
+
async resolveConfig(cfg, ctx) {
|
|
93
|
+
const { ttsEngine } = cfg;
|
|
94
|
+
// Same default as the former onnx-tts plugin: omitting `ttsEngine` → Chatterbox.
|
|
95
|
+
if (ttsEngine === "supertonic") {
|
|
96
|
+
return resolveSupertonicConfig(cfg);
|
|
97
|
+
}
|
|
98
|
+
return resolveChatterboxConfig(cfg, ctx);
|
|
99
|
+
},
|
|
100
|
+
createModel(params) {
|
|
101
|
+
const config = (params.modelConfig ?? {});
|
|
102
|
+
const artifacts = params.artifacts ?? {};
|
|
103
|
+
if (config.ttsEngine === "supertonic") {
|
|
104
|
+
return createSupertonicModel(params.modelId, config, params);
|
|
105
|
+
}
|
|
106
|
+
return createChatterboxModel(params.modelId, config, params, artifacts);
|
|
107
|
+
},
|
|
108
|
+
handlers: {
|
|
109
|
+
textToSpeech: defineHandler({
|
|
110
|
+
requestSchema: ttsRequestSchema,
|
|
111
|
+
responseSchema: ttsResponseSchema,
|
|
112
|
+
streaming: true,
|
|
113
|
+
cancel: { scope: "model", hard: true },
|
|
114
|
+
handler: async function* (request) {
|
|
115
|
+
const stream = textToSpeech(request);
|
|
116
|
+
try {
|
|
117
|
+
let result = await stream.next();
|
|
118
|
+
while (!result.done) {
|
|
119
|
+
yield {
|
|
120
|
+
type: "textToSpeech",
|
|
121
|
+
buffer: result.value.buffer,
|
|
122
|
+
done: false,
|
|
123
|
+
...(result.value.chunkIndex !== undefined
|
|
124
|
+
? { chunkIndex: result.value.chunkIndex }
|
|
125
|
+
: {}),
|
|
126
|
+
...(typeof result.value.sentenceChunk === "string" &&
|
|
127
|
+
result.value.sentenceChunk.length > 0
|
|
128
|
+
? { sentenceChunk: result.value.sentenceChunk }
|
|
129
|
+
: {}),
|
|
130
|
+
};
|
|
131
|
+
result = await stream.next();
|
|
132
|
+
}
|
|
133
|
+
const { modelExecutionMs, stats } = result.value;
|
|
134
|
+
yield attachModelExecutionMs({
|
|
135
|
+
type: "textToSpeech",
|
|
136
|
+
buffer: [],
|
|
137
|
+
done: true,
|
|
138
|
+
...(stats && { stats }),
|
|
139
|
+
}, modelExecutionMs);
|
|
140
|
+
}
|
|
141
|
+
finally {
|
|
142
|
+
await stream.return?.(undefined);
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
}),
|
|
146
|
+
textToSpeechStream: defineDuplexHandler({
|
|
147
|
+
requestSchema: textToSpeechStreamRequestSchema,
|
|
148
|
+
responseSchema: textToSpeechStreamResponseSchema,
|
|
149
|
+
streaming: true,
|
|
150
|
+
duplex: true,
|
|
151
|
+
cancel: { scope: "model", hard: true },
|
|
152
|
+
handler: async function* (request, inputStream) {
|
|
153
|
+
const stream = textToSpeechStream(request, inputStream);
|
|
154
|
+
try {
|
|
155
|
+
let result = await stream.next();
|
|
156
|
+
while (!result.done) {
|
|
157
|
+
yield {
|
|
158
|
+
type: "textToSpeechStream",
|
|
159
|
+
buffer: result.value.buffer,
|
|
160
|
+
done: false,
|
|
161
|
+
...(result.value.chunkIndex !== undefined
|
|
162
|
+
? { chunkIndex: result.value.chunkIndex }
|
|
163
|
+
: {}),
|
|
164
|
+
...(typeof result.value.sentenceChunk === "string" &&
|
|
165
|
+
result.value.sentenceChunk.length > 0
|
|
166
|
+
? { sentenceChunk: result.value.sentenceChunk }
|
|
167
|
+
: {}),
|
|
168
|
+
};
|
|
169
|
+
result = await stream.next();
|
|
170
|
+
}
|
|
171
|
+
const { modelExecutionMs, stats } = result.value;
|
|
172
|
+
yield attachModelExecutionMs({
|
|
173
|
+
type: "textToSpeechStream",
|
|
174
|
+
buffer: [],
|
|
175
|
+
done: true,
|
|
176
|
+
...(stats && { stats }),
|
|
177
|
+
}, modelExecutionMs);
|
|
178
|
+
}
|
|
179
|
+
finally {
|
|
180
|
+
await stream.return?.(undefined);
|
|
181
|
+
}
|
|
182
|
+
},
|
|
183
|
+
}),
|
|
184
|
+
},
|
|
185
|
+
logging: {
|
|
186
|
+
module: ttsAddonLogging,
|
|
187
|
+
namespace: ModelType.ttsGgml,
|
|
188
|
+
},
|
|
189
|
+
});
|
|
@@ -79,18 +79,23 @@ export declare const whisperPlugin: {
|
|
|
79
79
|
diffusion: "diffusion";
|
|
80
80
|
tts: "tts";
|
|
81
81
|
ocr: "ocr";
|
|
82
|
+
vla: "vla";
|
|
82
83
|
"llamacpp-completion": "llamacpp-completion";
|
|
83
84
|
"whispercpp-transcription": "whispercpp-transcription";
|
|
84
85
|
"llamacpp-embedding": "llamacpp-embedding";
|
|
85
86
|
"nmtcpp-translation": "nmtcpp-translation";
|
|
86
87
|
"onnx-tts": "onnx-tts";
|
|
88
|
+
"tts-ggml": "tts-ggml";
|
|
87
89
|
"parakeet-transcription": "parakeet-transcription";
|
|
88
90
|
"onnx-ocr": "onnx-ocr";
|
|
89
91
|
"sdcpp-generation": "sdcpp-generation";
|
|
92
|
+
"ggml-vla": "ggml-vla";
|
|
93
|
+
"ggml-classification": "ggml-classification";
|
|
90
94
|
llm: "llm";
|
|
91
95
|
whisper: "whisper";
|
|
92
96
|
nmt: "nmt";
|
|
93
97
|
parakeet: "parakeet";
|
|
98
|
+
classification: "classification";
|
|
94
99
|
}>, import("zod").ZodLiteral<"vad">]>>;
|
|
95
100
|
}, import("zod/v4/core").$strip>]>>;
|
|
96
101
|
}, import("zod/v4/core").$strip>;
|
|
@@ -253,9 +258,12 @@ export declare const whisperPlugin: {
|
|
|
253
258
|
speaking: import("zod").ZodBoolean;
|
|
254
259
|
probability: import("zod").ZodNumber;
|
|
255
260
|
}, import("zod/v4/core").$strip>>;
|
|
256
|
-
endOfTurn: import("zod").ZodOptional<import("zod").ZodObject<{
|
|
261
|
+
endOfTurn: import("zod").ZodOptional<import("zod").ZodPreprocess<import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
|
|
262
|
+
source: import("zod").ZodLiteral<"whisper">;
|
|
257
263
|
silenceDurationMs: import("zod").ZodNumber;
|
|
258
|
-
}, import("zod/v4/core").$strip
|
|
264
|
+
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
|
|
265
|
+
source: import("zod").ZodLiteral<"parakeet">;
|
|
266
|
+
}, import("zod/v4/core").$strip>], "source">>>;
|
|
259
267
|
type: import("zod").ZodLiteral<"transcribe">;
|
|
260
268
|
}, import("zod/v4/core").$strip>>;
|
|
261
269
|
transcribeStream: import("../../../../schemas/index").PluginHandlerDefinition<import("zod").ZodObject<{
|
|
@@ -266,6 +274,20 @@ export declare const whisperPlugin: {
|
|
|
266
274
|
emitVadEvents: import("zod").ZodOptional<import("zod").ZodBoolean>;
|
|
267
275
|
endOfTurnSilenceMs: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
268
276
|
vadRunIntervalMs: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
277
|
+
parakeetStreamingConfig: import("zod").ZodOptional<import("zod").ZodObject<{
|
|
278
|
+
chunkMs: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
279
|
+
historyMs: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
280
|
+
leftContextMs: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
281
|
+
rightLookaheadMs: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
282
|
+
emitPartials: import("zod").ZodOptional<import("zod").ZodBoolean>;
|
|
283
|
+
emitEnergyVad: import("zod").ZodOptional<import("zod").ZodBoolean>;
|
|
284
|
+
spkCacheEnable: import("zod").ZodOptional<import("zod").ZodBoolean>;
|
|
285
|
+
spkCacheLen: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
286
|
+
fifoLen: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
287
|
+
chunkLeftContextMs: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
288
|
+
chunkRightContextMs: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
289
|
+
spkCacheUpdatePeriod: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
290
|
+
}, import("zod/v4/core").$strip>>;
|
|
269
291
|
requestId: import("zod").ZodOptional<import("zod").ZodString>;
|
|
270
292
|
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
|
|
271
293
|
text: import("zod").ZodOptional<import("zod").ZodString>;
|
|
@@ -294,9 +316,12 @@ export declare const whisperPlugin: {
|
|
|
294
316
|
speaking: import("zod").ZodBoolean;
|
|
295
317
|
probability: import("zod").ZodNumber;
|
|
296
318
|
}, import("zod/v4/core").$strip>>;
|
|
297
|
-
endOfTurn: import("zod").ZodOptional<import("zod").ZodObject<{
|
|
319
|
+
endOfTurn: import("zod").ZodOptional<import("zod").ZodPreprocess<import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
|
|
320
|
+
source: import("zod").ZodLiteral<"whisper">;
|
|
298
321
|
silenceDurationMs: import("zod").ZodNumber;
|
|
299
|
-
}, import("zod/v4/core").$strip
|
|
322
|
+
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
|
|
323
|
+
source: import("zod").ZodLiteral<"parakeet">;
|
|
324
|
+
}, import("zod/v4/core").$strip>], "source">>>;
|
|
300
325
|
type: import("zod").ZodLiteral<"transcribeStream">;
|
|
301
326
|
}, import("zod/v4/core").$strip>>;
|
|
302
327
|
};
|
|
@@ -133,9 +133,20 @@ export const whisperPlugin = definePlugin({
|
|
|
133
133
|
continue;
|
|
134
134
|
}
|
|
135
135
|
if (value.type === "endOfTurn") {
|
|
136
|
+
// Whisper addon emits legacy `{ type, silenceDurationMs }` frames
|
|
137
|
+
// without `source`. Parakeet must never surface here.
|
|
138
|
+
if (value.source === "parakeet") {
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
if (typeof value.silenceDurationMs !== "number") {
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
136
144
|
yield {
|
|
137
145
|
type: "transcribeStream",
|
|
138
|
-
endOfTurn: {
|
|
146
|
+
endOfTurn: {
|
|
147
|
+
source: "whisper",
|
|
148
|
+
silenceDurationMs: value.silenceDurationMs,
|
|
149
|
+
},
|
|
139
150
|
};
|
|
140
151
|
continue;
|
|
141
152
|
}
|
|
@@ -3,6 +3,8 @@ import { llmConfigSchema, embedConfigSchema } from "../../../schemas/llamacpp-co
|
|
|
3
3
|
import { whisperConfigSchema, parakeetRuntimeConfigSchema, } from "../../../schemas/transcription-config.js";
|
|
4
4
|
import { ocrConfigSchema } from "../../../schemas/ocr.js";
|
|
5
5
|
import { sdcppConfigSchema } from "../../../schemas/sdcpp-config.js";
|
|
6
|
+
import { vlaConfigSchema } from "../../../schemas/vla.js";
|
|
7
|
+
import { classificationConfigSchema } from "../../../schemas/classification.js";
|
|
6
8
|
export const CANONICAL_TO_ALIAS = {
|
|
7
9
|
[ModelType.llamacppCompletion]: "llm",
|
|
8
10
|
[ModelType.llamacppEmbedding]: "embeddings",
|
|
@@ -10,8 +12,11 @@ export const CANONICAL_TO_ALIAS = {
|
|
|
10
12
|
[ModelType.parakeetTranscription]: "parakeet",
|
|
11
13
|
[ModelType.nmtcppTranslation]: "nmt",
|
|
12
14
|
[ModelType.onnxTts]: "tts",
|
|
15
|
+
[ModelType.ttsGgml]: "tts",
|
|
13
16
|
[ModelType.onnxOcr]: "ocr",
|
|
14
17
|
[ModelType.sdcppGeneration]: "diffusion",
|
|
18
|
+
[ModelType.ggmlVla]: "vla",
|
|
19
|
+
[ModelType.ggmlClassification]: "classification",
|
|
15
20
|
};
|
|
16
21
|
export const MODEL_CONFIG_SCHEMAS = {
|
|
17
22
|
[ModelType.llamacppCompletion]: llmConfigSchema,
|
|
@@ -20,6 +25,8 @@ export const MODEL_CONFIG_SCHEMAS = {
|
|
|
20
25
|
[ModelType.parakeetTranscription]: parakeetRuntimeConfigSchema.passthrough(),
|
|
21
26
|
[ModelType.onnxOcr]: ocrConfigSchema,
|
|
22
27
|
[ModelType.sdcppGeneration]: sdcppConfigSchema,
|
|
28
|
+
[ModelType.ggmlVla]: vlaConfigSchema,
|
|
29
|
+
[ModelType.ggmlClassification]: classificationConfigSchema,
|
|
23
30
|
};
|
|
24
31
|
// Ordered general → specific (later patterns override earlier)
|
|
25
32
|
export const BUILTIN_DEVICE_PATTERNS = [
|
|
@@ -9,7 +9,7 @@ import type { DisposableScope } from "./disposable-scope";
|
|
|
9
9
|
* The set is intentionally open-coded — adding a new kind is a one-line
|
|
10
10
|
* change and the union surfaces in editor autocomplete at every call site.
|
|
11
11
|
*/
|
|
12
|
-
export type RequestKind = "completion" | "embeddings" | "transcribe" | "translate" | "diffusion" | "tts" | "ocr" | "finetune" | "loadModel" | "downloadAsset" | "rag";
|
|
12
|
+
export type RequestKind = "completion" | "embeddings" | "transcribe" | "translate" | "diffusion" | "tts" | "ocr" | "vla" | "finetune" | "loadModel" | "downloadAsset" | "rag";
|
|
13
13
|
/**
|
|
14
14
|
* Lifecycle states a request transitions through. A new context starts in
|
|
15
15
|
* `"running"`. `cancel(...)` flips it to `"cancelling"` and aborts the
|
|
@@ -78,17 +78,17 @@ export async function suspendRuntime() {
|
|
|
78
78
|
return suspendRuntime();
|
|
79
79
|
}
|
|
80
80
|
state = "suspending";
|
|
81
|
-
logger.info(`⏸️ Suspending runtime (${
|
|
81
|
+
logger.info(`⏸️ Suspending runtime (${stores.size} stores, ${swarms.size} swarms)`);
|
|
82
82
|
transitionPromise = (async () => {
|
|
83
83
|
const swarmSnapshot = Array.from(swarms.entries());
|
|
84
84
|
const storeSnapshot = Array.from(stores.entries());
|
|
85
|
+
await runPhase(storeSnapshot, stores, async (store) => {
|
|
86
|
+
await store.suspend();
|
|
87
|
+
}, "suspend-store");
|
|
85
88
|
await runPhase(swarmSnapshot, swarms, async (swarm) => {
|
|
86
89
|
if (!swarm.suspended)
|
|
87
90
|
await swarm.suspend();
|
|
88
91
|
}, "suspend-swarm");
|
|
89
|
-
await runPhase(storeSnapshot, stores, async (store) => {
|
|
90
|
-
await store.suspend();
|
|
91
|
-
}, "suspend-store");
|
|
92
92
|
})()
|
|
93
93
|
.then(() => {
|
|
94
94
|
state = "suspended";
|
|
@@ -116,16 +116,16 @@ export async function resumeRuntime() {
|
|
|
116
116
|
return resumeRuntime();
|
|
117
117
|
}
|
|
118
118
|
state = "resuming";
|
|
119
|
-
logger.info(`▶️ Resuming runtime (${
|
|
119
|
+
logger.info(`▶️ Resuming runtime (${swarms.size} swarms, ${stores.size} stores)`);
|
|
120
120
|
transitionPromise = (async () => {
|
|
121
|
-
const storeSnapshot = Array.from(stores.entries());
|
|
122
121
|
const swarmSnapshot = Array.from(swarms.entries());
|
|
123
|
-
|
|
124
|
-
await store.resume();
|
|
125
|
-
}, "resume-store");
|
|
122
|
+
const storeSnapshot = Array.from(stores.entries());
|
|
126
123
|
await runPhase(swarmSnapshot, swarms, async (swarm) => {
|
|
127
124
|
await swarm.resume();
|
|
128
125
|
}, "resume-swarm");
|
|
126
|
+
await runPhase(storeSnapshot, stores, async (store) => {
|
|
127
|
+
await store.resume();
|
|
128
|
+
}, "resume-store");
|
|
129
129
|
})()
|
|
130
130
|
.then(() => {
|
|
131
131
|
state = "active";
|
package/dist/server/env.js
CHANGED
|
@@ -11,7 +11,10 @@ let validatedEnv = null;
|
|
|
11
11
|
* Returns whether RPC config was parsed from arguments.
|
|
12
12
|
*/
|
|
13
13
|
export function initEnv() {
|
|
14
|
-
const defaultHomeDir =
|
|
14
|
+
const defaultHomeDir =
|
|
15
|
+
// Snap's HOME can be revision-scoped; SNAP_USER_COMMON is stable.
|
|
16
|
+
process.env["SNAP_USER_COMMON"] ??
|
|
17
|
+
process.env["HOME"] ??
|
|
15
18
|
process.env["USERPROFILE"] ??
|
|
16
19
|
"/tmp";
|
|
17
20
|
let envConfig = {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { registerPlugin, getPlugin, getPluginHandler, hasPlugin, getAllPlugins, clearPlugins, unregisterPlugin, } from "./registry";
|
|
1
|
+
export { registerPlugin, registerPlugins, getPlugin, getPluginHandler, hasPlugin, getAllPlugins, clearPlugins, unregisterPlugin, } from "./registry";
|
|
2
2
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { registerPlugin, getPlugin, getPluginHandler, hasPlugin, getAllPlugins, clearPlugins, unregisterPlugin, } from "./registry.js";
|
|
1
|
+
export { registerPlugin, registerPlugins, getPlugin, getPluginHandler, hasPlugin, getAllPlugins, clearPlugins, unregisterPlugin, } from "./registry.js";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type QvacPlugin, type PluginHandlerDefinition } from "../../schemas/plugin";
|
|
2
2
|
export declare function registerPlugin(plugin: QvacPlugin): void;
|
|
3
|
+
export declare function registerPlugins(pluginList: readonly QvacPlugin[]): void;
|
|
3
4
|
export declare function getPlugin(modelType: string): QvacPlugin | undefined;
|
|
4
5
|
export declare function getPluginHandler(modelType: string, handlerName: string): PluginHandlerDefinition | undefined;
|
|
5
6
|
export declare function hasPlugin(modelType: string): boolean;
|
|
@@ -43,6 +43,11 @@ export function registerPlugin(plugin) {
|
|
|
43
43
|
loggingModule.setLogger(createAddonLoggerCallback(plugin.logging.namespace));
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
|
+
export function registerPlugins(pluginList) {
|
|
47
|
+
for (const plugin of pluginList) {
|
|
48
|
+
registerPlugin(plugin);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
46
51
|
export function getPlugin(modelType) {
|
|
47
52
|
return plugins.get(modelType);
|
|
48
53
|
}
|
|
@@ -27,7 +27,9 @@ import { handleFinetune } from "./handlers/finetune.js";
|
|
|
27
27
|
import { handleHeartbeatDelegated } from "./handlers/heartbeat-delegated.js";
|
|
28
28
|
import { handleCancelDelegated } from "./handlers/cancel-delegated.js";
|
|
29
29
|
import { handleDiffusionStream } from "./handlers/diffusion-stream.js";
|
|
30
|
+
import { handleVideoStream } from "./handlers/video-stream.js";
|
|
30
31
|
import { handleUpscaleStream } from "./handlers/upscale-stream.js";
|
|
32
|
+
import { handleClassify } from "./handlers/classify.js";
|
|
31
33
|
import { handlePluginInvoke, handlePluginInvokeStream, } from "./handlers/plugin-invoke.js";
|
|
32
34
|
import { handleModelRegistryList, handleModelRegistrySearch, handleModelRegistryGetModel, } from "./handlers/registry.js";
|
|
33
35
|
import { handleSuspend } from "./handlers/suspend.js";
|
|
@@ -122,7 +124,9 @@ export const registry = {
|
|
|
122
124
|
textToSpeechStream: { type: "duplex", handler: handleTextToSpeechStream },
|
|
123
125
|
ocrStream: { type: "stream", handler: handleOCRStream },
|
|
124
126
|
diffusionStream: { type: "stream", handler: handleDiffusionStream },
|
|
127
|
+
videoStream: { type: "stream", handler: handleVideoStream },
|
|
125
128
|
upscaleStream: { type: "stream", handler: handleUpscaleStream },
|
|
129
|
+
classify: { type: "stream", handler: handleClassify },
|
|
126
130
|
pluginInvokeStream: { type: "stream", handler: handlePluginInvokeStream },
|
|
127
131
|
// Handlers with delegation support
|
|
128
132
|
loadModel: {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Request } from "../../schemas/index";
|
|
2
|
+
import type { HandlerEntry } from "./handler-utils";
|
|
3
|
+
export interface HandlerSelection {
|
|
4
|
+
handler: HandlerEntry["handler"];
|
|
5
|
+
isDelegated: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function selectHandler(entry: HandlerEntry, request: Request): HandlerSelection;
|
|
8
|
+
export declare function handlerSupportsProgress(entry: HandlerEntry, request: Request): boolean;
|
|
9
|
+
//# sourceMappingURL=handler-selection.d.ts.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function selectHandler(entry, request) {
|
|
2
|
+
const isDelegated = !!(entry.delegatedHandler && entry.isDelegated?.(request));
|
|
3
|
+
return {
|
|
4
|
+
handler: isDelegated ? entry.delegatedHandler : entry.handler,
|
|
5
|
+
isDelegated,
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
export function handlerSupportsProgress(entry, request) {
|
|
9
|
+
return !!("withProgress" in request &&
|
|
10
|
+
request.withProgress &&
|
|
11
|
+
(typeof entry.supportsProgress === "function"
|
|
12
|
+
? entry.supportsProgress(request)
|
|
13
|
+
: entry.supportsProgress));
|
|
14
|
+
}
|
|
@@ -6,6 +6,7 @@ import { setRuntimeContext } from "../bare/registry/runtime-context-registry.js"
|
|
|
6
6
|
import {} from "./profiling/index.js";
|
|
7
7
|
import { isTerminalChunk } from "./rpc-utils.js";
|
|
8
8
|
import { createProgressThrottle } from "./progress-throttle.js";
|
|
9
|
+
import { handlerSupportsProgress, selectHandler, } from "./handler-selection.js";
|
|
9
10
|
function getProfilingMetaFromRequest(request) {
|
|
10
11
|
if (PROFILING_KEY in request) {
|
|
11
12
|
return request[PROFILING_KEY];
|
|
@@ -74,9 +75,7 @@ async function executeProgressHandler(req, request, handler, profiler, isDelegat
|
|
|
74
75
|
const stream = req.createResponseStream();
|
|
75
76
|
profiler.startHandler();
|
|
76
77
|
const writeBatch = (updates) => {
|
|
77
|
-
const payload = updates
|
|
78
|
-
.map((u) => profiler.serialize(u, false))
|
|
79
|
-
.join("\n");
|
|
78
|
+
const payload = updates.map((u) => profiler.serialize(u, false)).join("\n");
|
|
80
79
|
stream.write(payload + "\n", "utf-8");
|
|
81
80
|
};
|
|
82
81
|
const throttle = createProgressThrottle(writeBatch);
|
|
@@ -105,9 +104,7 @@ async function executeProgressHandler(req, request, handler, profiler, isDelegat
|
|
|
105
104
|
}
|
|
106
105
|
}
|
|
107
106
|
export async function executeDuplexHandler(_req, request, entry, inputStream, outputStream, profiler) {
|
|
108
|
-
const handler = entry
|
|
109
|
-
? entry.delegatedHandler
|
|
110
|
-
: entry.handler;
|
|
107
|
+
const { handler } = selectHandler(entry, request);
|
|
111
108
|
profiler.startHandler();
|
|
112
109
|
try {
|
|
113
110
|
for await (const response of handler(request, inputStream)) {
|
|
@@ -127,13 +124,8 @@ export async function executeDuplexHandler(_req, request, entry, inputStream, ou
|
|
|
127
124
|
}
|
|
128
125
|
// Unified handler executor with delegation and progress support
|
|
129
126
|
export async function executeHandler(req, request, entry, profiler) {
|
|
130
|
-
const isDelegated =
|
|
131
|
-
const
|
|
132
|
-
const wantsProgress = "withProgress" in request &&
|
|
133
|
-
request.withProgress &&
|
|
134
|
-
(typeof entry.supportsProgress === "function"
|
|
135
|
-
? entry.supportsProgress(request)
|
|
136
|
-
: entry.supportsProgress);
|
|
127
|
+
const { handler, isDelegated } = selectHandler(entry, request);
|
|
128
|
+
const wantsProgress = handlerSupportsProgress(entry, request);
|
|
137
129
|
if (entry.type === "duplex") {
|
|
138
130
|
throw new PluginHandlerTypeMismatchError(request.type, "reply or stream", "duplex");
|
|
139
131
|
}
|
|
@@ -20,6 +20,7 @@ import { handleFinetune } from "./finetune";
|
|
|
20
20
|
import { handleOCRStream } from "./ocr-stream";
|
|
21
21
|
import { handleHeartbeat } from "./heartbeat";
|
|
22
22
|
import { handleDiffusionStream } from "./diffusion-stream";
|
|
23
|
+
import { handleVideoStream } from "./video-stream";
|
|
23
24
|
import { handleUpscaleStream } from "./upscale-stream";
|
|
24
25
|
import { handlePluginInvoke, handlePluginInvokeStream } from "./plugin-invoke";
|
|
25
26
|
import { handleModelRegistryList, handleModelRegistrySearch, handleModelRegistryGetModel } from "./registry";
|
|
@@ -49,6 +50,7 @@ export declare const handlers: {
|
|
|
49
50
|
finetune: typeof handleFinetune;
|
|
50
51
|
ocrStream: typeof handleOCRStream;
|
|
51
52
|
diffusionStream: typeof handleDiffusionStream;
|
|
53
|
+
videoStream: typeof handleVideoStream;
|
|
52
54
|
upscaleStream: typeof handleUpscaleStream;
|
|
53
55
|
pluginInvoke: typeof handlePluginInvoke;
|
|
54
56
|
pluginInvokeStream: typeof handlePluginInvokeStream;
|
|
@@ -20,6 +20,7 @@ import { handleFinetune } from "./finetune.js";
|
|
|
20
20
|
import { handleOCRStream } from "./ocr-stream.js";
|
|
21
21
|
import { handleHeartbeat } from "./heartbeat.js";
|
|
22
22
|
import { handleDiffusionStream } from "./diffusion-stream.js";
|
|
23
|
+
import { handleVideoStream } from "./video-stream.js";
|
|
23
24
|
import { handleUpscaleStream } from "./upscale-stream.js";
|
|
24
25
|
import { handlePluginInvoke, handlePluginInvokeStream } from "./plugin-invoke.js";
|
|
25
26
|
import { handleModelRegistryList, handleModelRegistrySearch, handleModelRegistryGetModel, } from "./registry.js";
|
|
@@ -49,6 +50,7 @@ export const handlers = {
|
|
|
49
50
|
finetune: handleFinetune,
|
|
50
51
|
ocrStream: handleOCRStream,
|
|
51
52
|
diffusionStream: handleDiffusionStream,
|
|
53
|
+
videoStream: handleVideoStream,
|
|
52
54
|
upscaleStream: handleUpscaleStream,
|
|
53
55
|
pluginInvoke: handlePluginInvoke,
|
|
54
56
|
pluginInvokeStream: handlePluginInvokeStream,
|
|
@@ -151,7 +151,10 @@ export async function handleLoadModel(request, progressCallback) {
|
|
|
151
151
|
if ("modelPath" in pluginArtifacts) {
|
|
152
152
|
throw new ModelLoadFailedError("Plugin returned reserved key \"modelPath\" in artifacts; primary model resolution is core-owned");
|
|
153
153
|
}
|
|
154
|
-
|
|
154
|
+
// An empty resolved path is legitimate when the plugin opts out of
|
|
155
|
+
// primary-model-path validation (bundled weights). For every other
|
|
156
|
+
// plugin, an empty path means resolution failed and we must abort.
|
|
157
|
+
if (!resolvedModelPath && !plugin.skipPrimaryModelPathValidation) {
|
|
155
158
|
throw new ModelLoadFailedError("modelPath resolution failed");
|
|
156
159
|
}
|
|
157
160
|
const loadResult = await loadModel({
|
|
@@ -79,6 +79,15 @@ async function resolveModelPathCore(modelSrc, progressCallback, seed, mode, sign
|
|
|
79
79
|
throw new InferenceCancelledError(hooks?.requestBinding?.requestId ?? "unknown");
|
|
80
80
|
}
|
|
81
81
|
const srcString = modelInputToSrcSchema.parse(modelSrc);
|
|
82
|
+
// Empty modelSrc is reserved for plugins that ship bundled weights
|
|
83
|
+
// (e.g. `@qvac/classification-ggml`). The handler skips this resolver
|
|
84
|
+
// for them when `skipPrimaryModelPathValidation` is set, but if it
|
|
85
|
+
// somehow gets called we return an empty path so the plugin's
|
|
86
|
+
// `params.modelPath` falls through to undefined instead of being set
|
|
87
|
+
// to the cache directory itself.
|
|
88
|
+
if (srcString === "") {
|
|
89
|
+
return { path: "", sourceType: "filesystem" };
|
|
90
|
+
}
|
|
82
91
|
// Parse hyperdrive URLs if present
|
|
83
92
|
let hyperdriveKey;
|
|
84
93
|
let actualModelSrc = srcString;
|
|
@@ -242,6 +242,29 @@ registerOperationMetrics({
|
|
|
242
242
|
return Object.keys(gauges).length > 0 ? gauges : undefined;
|
|
243
243
|
},
|
|
244
244
|
});
|
|
245
|
+
registerOperationMetrics({
|
|
246
|
+
op: "videoStream",
|
|
247
|
+
kind: "handler",
|
|
248
|
+
getTags: (req) => (req.modelId ? { modelId: req.modelId } : {}),
|
|
249
|
+
fromFinalChunk: (res) => {
|
|
250
|
+
if (!res.stats)
|
|
251
|
+
return undefined;
|
|
252
|
+
const gauges = {};
|
|
253
|
+
if (res.stats.generationMs !== undefined)
|
|
254
|
+
gauges["generationMs"] = res.stats.generationMs;
|
|
255
|
+
if (res.stats.totalSteps !== undefined)
|
|
256
|
+
gauges["totalSteps"] = res.stats.totalSteps;
|
|
257
|
+
if (res.stats.totalVideos !== undefined)
|
|
258
|
+
gauges["totalVideos"] = res.stats.totalVideos;
|
|
259
|
+
if (res.stats.totalVideoFrames !== undefined)
|
|
260
|
+
gauges["totalVideoFrames"] = res.stats.totalVideoFrames;
|
|
261
|
+
if (res.stats.videoFrames !== undefined)
|
|
262
|
+
gauges["videoFrames"] = res.stats.videoFrames;
|
|
263
|
+
if (res.stats.fps !== undefined)
|
|
264
|
+
gauges["fps"] = res.stats.fps;
|
|
265
|
+
return Object.keys(gauges).length > 0 ? gauges : undefined;
|
|
266
|
+
},
|
|
267
|
+
});
|
|
245
268
|
registerOperationMetrics({
|
|
246
269
|
op: "pluginInvoke",
|
|
247
270
|
kind: "handler",
|
|
@@ -14,7 +14,7 @@ export function transformConfigForReload(modelType, config) {
|
|
|
14
14
|
case ModelType.llamacppCompletion:
|
|
15
15
|
case ModelType.llamacppEmbedding:
|
|
16
16
|
case ModelType.nmtcppTranslation:
|
|
17
|
-
case ModelType.
|
|
17
|
+
case ModelType.ttsGgml:
|
|
18
18
|
// Return as-is for now
|
|
19
19
|
return config;
|
|
20
20
|
default:
|