@qvac/sdk 0.6.1 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -24
- package/NOTICE +632 -0
- package/README.md +2 -1
- package/dist/client/api/embed.js +1 -4
- package/dist/client/api/get-model-info.d.ts +10 -3
- package/dist/client/api/index.d.ts +2 -0
- package/dist/client/api/index.js +2 -0
- package/dist/client/api/invoke-plugin.d.ts +14 -0
- package/dist/client/api/invoke-plugin.js +38 -0
- package/dist/client/api/registry.d.ts +14 -0
- package/dist/client/api/registry.js +37 -0
- package/dist/client/api/transcribe.js +0 -4
- package/dist/client/api/unload-model.js +1 -1
- package/dist/client/config-loader/resolve-config.node.d.ts +3 -2
- package/dist/client/config-loader/resolve-config.node.js +31 -4
- package/dist/client/init-hooks.js +2 -1
- package/dist/client/rpc/bare-client.d.ts +2 -0
- package/dist/client/rpc/bare-client.js +48 -7
- package/dist/client/rpc/expo-device-info.d.ts +6 -0
- package/dist/client/rpc/expo-device-info.js +32 -0
- package/dist/client/rpc/expo-rpc-client.js +9 -32
- package/dist/client/rpc/node-rpc-client.d.ts +1 -1
- package/dist/client/rpc/node-rpc-client.js +201 -28
- package/dist/client/rpc/rpc-client.d.ts +1 -1
- package/dist/client/rpc/rpc-client.js +2 -2
- package/dist/constants/index.d.ts +1 -0
- package/dist/constants/index.js +1 -0
- package/dist/constants/registry.d.ts +2 -0
- package/dist/constants/registry.js +1 -0
- package/dist/examples/cache-management.js +2 -2
- package/dist/examples/config/plugins/plugins.config.d.ts +5 -0
- package/dist/examples/config/plugins/plugins.config.js +4 -0
- package/dist/examples/download-with-blind-relays.js +1 -1
- package/dist/examples/llamacpp-multimodal.js +3 -3
- package/dist/examples/llamacpp-native-tools.js +2 -2
- package/dist/examples/mcp-websearch.js +2 -2
- package/dist/examples/multi-model-demo.js +2 -2
- package/dist/examples/ocr-fasttext.js +4 -4
- package/dist/examples/parallel-download.js +2 -2
- package/dist/examples/plugins.d.ts +14 -0
- package/dist/examples/plugins.js +129 -0
- package/dist/examples/registry-query.d.ts +2 -0
- package/dist/examples/registry-query.js +87 -0
- package/dist/examples/translation/translation-bergamot-batch.js +2 -2
- package/dist/examples/translation/translation-bergamot.js +4 -4
- package/dist/examples/translation/translation-opus.js +2 -2
- package/dist/examples/translation/translation-stream.js +2 -2
- package/dist/examples/tts/chatterbox.d.ts +2 -0
- package/dist/examples/tts/chatterbox.js +59 -0
- package/dist/examples/tts/supertonic.d.ts +2 -0
- package/dist/examples/tts/supertonic.js +51 -0
- package/dist/examples/tts/utils.d.ts +17 -0
- package/dist/examples/tts/utils.js +93 -0
- package/dist/examples/whispercpp-filesystem.js +2 -3
- package/dist/examples/whispercpp-microphone-record.js +1 -2
- package/dist/examples/whispercpp-prompt.js +2 -3
- package/dist/expo/plugins/index.d.ts +3 -0
- package/dist/expo/plugins/index.js +3 -0
- package/dist/expo/plugins/resolve-sdk-package-dir.d.ts +15 -0
- package/dist/expo/plugins/resolve-sdk-package-dir.js +31 -0
- package/dist/expo/plugins/withAndroidArchitecture.d.ts +8 -0
- package/dist/expo/plugins/withAndroidArchitecture.js +52 -0
- package/dist/expo/plugins/withAndroidNdkVersion.d.ts +8 -0
- package/dist/expo/plugins/withAndroidNdkVersion.js +31 -0
- package/dist/expo/plugins/withDeviceInfo.d.ts +10 -0
- package/dist/expo/plugins/withDeviceInfo.js +48 -0
- package/dist/expo/plugins/withMobileBundle.d.ts +5 -2
- package/dist/expo/plugins/withMobileBundle.js +121 -65
- package/dist/expo/plugins/withQvacSDK.d.ts +4 -0
- package/dist/expo/plugins/withQvacSDK.js +26 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +5 -5
- package/dist/models/{hyperdrive → registry}/index.js +1 -1
- package/dist/models/registry/models.d.ts +9056 -0
- package/dist/models/registry/models.js +9351 -0
- package/dist/models/update-models/codegen.d.ts +3 -0
- package/dist/models/update-models/codegen.js +135 -0
- package/dist/models/update-models/history.d.ts +13 -0
- package/dist/models/update-models/history.js +88 -0
- package/dist/models/update-models/index.d.ts +2 -0
- package/dist/models/update-models/index.js +124 -0
- package/dist/models/update-models/naming.d.ts +4 -0
- package/dist/models/update-models/naming.js +314 -0
- package/dist/models/update-models/processing.d.ts +8 -0
- package/dist/models/update-models/processing.js +67 -0
- package/dist/models/update-models/registry.d.ts +4 -0
- package/dist/models/update-models/registry.js +67 -0
- package/dist/models/update-models/shards.d.ts +4 -0
- package/dist/models/update-models/shards.js +57 -0
- package/dist/models/update-models/types.d.ts +60 -0
- package/dist/models/update-models/types.js +1 -0
- package/dist/models/update-models/utils.d.ts +3 -0
- package/dist/models/update-models/utils.js +21 -0
- package/dist/pear/pre.d.ts +18 -0
- package/dist/pear/pre.js +433 -0
- package/dist/schemas/common.d.ts +286 -32
- package/dist/schemas/common.js +12 -0
- package/dist/schemas/download-asset.d.ts +35 -11
- package/dist/schemas/download-asset.js +5 -1
- package/dist/schemas/engine-addon-map.d.ts +5 -0
- package/dist/schemas/engine-addon-map.js +49 -0
- package/dist/schemas/get-model-info.d.ts +32 -16
- package/dist/schemas/get-model-info.js +17 -8
- package/dist/schemas/index.d.ts +4 -1
- package/dist/schemas/index.js +4 -4
- package/dist/schemas/load-model.d.ts +2224 -900
- package/dist/schemas/load-model.js +130 -25
- package/dist/schemas/model-src-utils.d.ts +30 -12
- package/dist/schemas/model-src-utils.js +5 -2
- package/dist/schemas/model-types.d.ts +15 -4
- package/dist/schemas/model-types.js +21 -4
- package/dist/schemas/path-validation.d.ts +10 -0
- package/dist/schemas/path-validation.js +22 -0
- package/dist/schemas/plugin.d.ts +180 -0
- package/dist/schemas/plugin.js +132 -0
- package/dist/schemas/rag.d.ts +2 -2
- package/dist/schemas/rag.js +7 -3
- package/dist/schemas/registry.d.ts +338 -0
- package/dist/schemas/registry.js +91 -0
- package/dist/schemas/sdk-errors-client.d.ts +6 -6
- package/dist/schemas/sdk-errors-client.js +15 -15
- package/dist/schemas/sdk-errors-registry.d.ts +6 -0
- package/dist/schemas/sdk-errors-registry.js +8 -0
- package/dist/schemas/sdk-errors-server.d.ts +16 -2
- package/dist/schemas/sdk-errors-server.js +90 -10
- package/dist/schemas/text-to-speech.d.ts +670 -1
- package/dist/schemas/text-to-speech.js +51 -2
- package/dist/schemas/translate.d.ts +2 -2
- package/dist/scripts/run-security-tests-bare.d.ts +2 -0
- package/dist/scripts/run-security-tests-bare.js +78 -0
- package/dist/scripts/run-security-tests.d.ts +2 -0
- package/dist/scripts/run-security-tests.js +22 -0
- package/dist/server/bare/delegate-rpc-client.d.ts +6 -0
- package/dist/server/bare/delegate-rpc-client.js +136 -56
- package/dist/server/bare/{addons/llamacpp-embedding/handlers → ops}/embed.d.ts +1 -1
- package/dist/server/bare/{addons/llamacpp-embedding/handlers → ops}/embed.js +3 -3
- package/dist/server/bare/{addons/llamacpp-completion → ops}/kv-cache-utils.js +6 -6
- package/dist/server/bare/{addons → ops}/load-model.js +32 -42
- package/dist/server/bare/{addons/nmtcpp-translation/handlers → ops}/translate.d.ts +1 -1
- package/dist/server/bare/{addons/nmtcpp-translation/handlers → ops}/translate.js +5 -4
- package/dist/server/bare/plugins/index.d.ts +7 -0
- package/dist/server/bare/plugins/index.js +6 -0
- package/dist/server/bare/{addons/llamacpp-completion → plugins/llamacpp-completion/ops}/cache-logger.js +1 -1
- package/dist/server/bare/{addons/llamacpp-completion/handlers → plugins/llamacpp-completion/ops}/completion-stream.d.ts +1 -1
- package/dist/server/bare/{addons/llamacpp-completion/handlers → plugins/llamacpp-completion/ops}/completion-stream.js +2 -3
- package/dist/server/bare/plugins/llamacpp-completion/plugin.d.ts +115 -0
- package/dist/server/bare/plugins/llamacpp-completion/plugin.js +142 -0
- package/dist/server/bare/plugins/llamacpp-embedding/plugin.d.ts +24 -0
- package/dist/server/bare/plugins/llamacpp-embedding/plugin.js +73 -0
- package/dist/server/bare/plugins/nmtcpp-translation/plugin.d.ts +45 -0
- package/dist/server/bare/plugins/nmtcpp-translation/plugin.js +97 -0
- package/dist/server/bare/{addons/onnx-ocr/handlers → plugins/onnx-ocr/ops}/ocr-stream.js +2 -1
- package/dist/server/bare/plugins/onnx-ocr/plugin.d.ts +38 -0
- package/dist/server/bare/{addons/onnx-ocr/create-model.js → plugins/onnx-ocr/plugin.js} +39 -2
- package/dist/server/bare/{addons/onnx-tts/handlers → plugins/onnx-tts/ops}/text-to-speech.js +23 -1
- package/dist/server/bare/plugins/onnx-tts/plugin.d.ts +26 -0
- package/dist/server/bare/plugins/onnx-tts/plugin.js +162 -0
- package/dist/server/bare/plugins/onnx-tts/wav-helper.d.ts +14 -0
- package/dist/server/bare/plugins/onnx-tts/wav-helper.js +107 -0
- package/dist/server/bare/plugins/whispercpp-transcription/ops/transcribe-stream.d.ts +3 -0
- package/dist/server/bare/{addons/whispercpp-transcription/handlers → plugins/whispercpp-transcription/ops}/transcribe-stream.js +1 -2
- package/dist/server/bare/plugins/whispercpp-transcription/plugin.d.ts +31 -0
- package/dist/server/bare/plugins/whispercpp-transcription/plugin.js +74 -0
- package/dist/server/bare/rag-hyperdb/handlers/ingest.js +1 -1
- package/dist/server/bare/rag-hyperdb/handlers/search.js +1 -1
- package/dist/server/bare/rag-hyperdb/rag-workspace-manager.js +2 -1
- package/dist/server/bare/registry/config-registry.js +1 -1
- package/dist/server/bare/registry/registry-client.d.ts +5 -0
- package/dist/server/bare/registry/registry-client.js +37 -0
- package/dist/server/env.d.ts +22 -0
- package/dist/server/env.js +57 -0
- package/dist/server/plugins/index.d.ts +2 -0
- package/dist/server/plugins/index.js +1 -0
- package/dist/server/plugins/registry.d.ts +9 -0
- package/dist/server/plugins/registry.js +75 -0
- package/dist/server/rpc/delegate-transport.d.ts +11 -0
- package/dist/server/rpc/delegate-transport.js +60 -0
- package/dist/server/rpc/handle-request.d.ts +0 -9
- package/dist/server/rpc/handle-request.js +13 -321
- package/dist/server/rpc/handler-registry.d.ts +3 -0
- package/dist/server/rpc/handler-registry.js +84 -0
- package/dist/server/rpc/handler-utils.d.ts +22 -0
- package/dist/server/rpc/handler-utils.js +87 -0
- package/dist/server/rpc/handlers/cancelHandler.js +1 -1
- package/dist/server/rpc/handlers/completion-stream-delegated.js +1 -1
- package/dist/server/rpc/handlers/completion-stream.js +2 -43
- package/dist/server/rpc/handlers/delete-cache.js +1 -1
- package/dist/server/rpc/handlers/embed.js +2 -21
- package/dist/server/rpc/handlers/get-model-info.js +19 -15
- package/dist/server/rpc/handlers/index.d.ts +9 -0
- package/dist/server/rpc/handlers/index.js +9 -0
- package/dist/server/rpc/handlers/load-model/download-manager.d.ts +1 -0
- package/dist/server/rpc/handlers/load-model/download-manager.js +3 -0
- package/dist/server/rpc/handlers/load-model/handler.js +47 -24
- package/dist/server/rpc/handlers/load-model/http.js +3 -2
- package/dist/server/rpc/handlers/load-model/hyperdrive.js +14 -10
- package/dist/server/rpc/handlers/load-model/registry.d.ts +10 -0
- package/dist/server/rpc/handlers/load-model/registry.js +571 -0
- package/dist/server/rpc/handlers/load-model/resolve.js +18 -5
- package/dist/server/rpc/handlers/load-model-delegated.js +4 -2
- package/dist/server/rpc/handlers/ocr-stream.js +2 -37
- package/dist/server/rpc/handlers/ping.d.ts +3 -0
- package/dist/server/rpc/handlers/ping.js +3 -0
- package/dist/server/rpc/handlers/plugin-dispatch.d.ts +15 -0
- package/dist/server/rpc/handlers/plugin-dispatch.js +54 -0
- package/dist/server/rpc/handlers/plugin-invoke.d.ts +4 -0
- package/dist/server/rpc/handlers/plugin-invoke.js +87 -0
- package/dist/server/rpc/handlers/registry.d.ts +5 -0
- package/dist/server/rpc/handlers/registry.js +157 -0
- package/dist/server/rpc/handlers/text-to-speech.js +2 -5
- package/dist/server/rpc/handlers/transcribe-stream.js +2 -30
- package/dist/server/rpc/handlers/translate.js +2 -42
- package/dist/server/rpc/handlers/unload-model.js +1 -1
- package/dist/server/rpc/index.d.ts +1 -1
- package/dist/server/utils/archive.d.ts +1 -0
- package/dist/server/utils/archive.js +10 -2
- package/dist/server/utils/cache.d.ts +5 -0
- package/dist/server/utils/cache.js +26 -2
- package/dist/server/utils/gguf-tensor-extractor.js +3 -3
- package/dist/server/utils/index.d.ts +1 -1
- package/dist/server/utils/index.js +1 -1
- package/dist/server/utils/path-security.d.ts +12 -0
- package/dist/server/utils/path-security.js +25 -0
- package/dist/server/utils/shard-utils.js +3 -3
- package/dist/server/worker-core.d.ts +6 -0
- package/dist/server/worker-core.js +88 -0
- package/dist/server/worker.d.ts +4 -5
- package/dist/server/worker.js +18 -116
- package/dist/utils/errors-client.d.ts +9 -6
- package/dist/utils/errors-client.js +19 -11
- package/dist/utils/errors-server.d.ts +44 -5
- package/dist/utils/errors-server.js +82 -9
- package/dist/utils/path-sanitize.d.ts +17 -0
- package/dist/utils/path-sanitize.js +54 -0
- package/expo/plugins/patches/android-link.mjs +63 -0
- package/expo/plugins/patches/ios-link.mjs +63 -0
- package/package.json +72 -10
- package/dist/examples/text-to-speech.d.ts +0 -3
- package/dist/examples/text-to-speech.js +0 -137
- package/dist/models/hyperdrive/models.d.ts +0 -4003
- package/dist/models/hyperdrive/models.js +0 -4282
- package/dist/server/bare/addons/index.d.ts +0 -4
- package/dist/server/bare/addons/index.js +0 -3
- package/dist/server/bare/addons/llamacpp-completion/create-model.d.ts +0 -8
- package/dist/server/bare/addons/llamacpp-completion/create-model.js +0 -43
- package/dist/server/bare/addons/llamacpp-completion/index.d.ts +0 -4
- package/dist/server/bare/addons/llamacpp-completion/index.js +0 -3
- package/dist/server/bare/addons/llamacpp-embedding/create-model.d.ts +0 -8
- package/dist/server/bare/addons/llamacpp-embedding/create-model.js +0 -38
- package/dist/server/bare/addons/llamacpp-embedding/index.d.ts +0 -3
- package/dist/server/bare/addons/llamacpp-embedding/index.js +0 -2
- package/dist/server/bare/addons/nmtcpp-translation/create-model.d.ts +0 -8
- package/dist/server/bare/addons/nmtcpp-translation/create-model.js +0 -52
- package/dist/server/bare/addons/nmtcpp-translation/index.d.ts +0 -3
- package/dist/server/bare/addons/nmtcpp-translation/index.js +0 -2
- package/dist/server/bare/addons/onnx-ocr/create-model.d.ts +0 -10
- package/dist/server/bare/addons/onnx-ocr/index.d.ts +0 -3
- package/dist/server/bare/addons/onnx-ocr/index.js +0 -2
- package/dist/server/bare/addons/onnx-tts/create-model.d.ts +0 -10
- package/dist/server/bare/addons/onnx-tts/create-model.js +0 -25
- package/dist/server/bare/addons/onnx-tts/index.d.ts +0 -3
- package/dist/server/bare/addons/onnx-tts/index.js +0 -2
- package/dist/server/bare/addons/whispercpp-transcription/create-model.d.ts +0 -10
- package/dist/server/bare/addons/whispercpp-transcription/create-model.js +0 -37
- package/dist/server/bare/addons/whispercpp-transcription/handlers/transcribe-stream.d.ts +0 -3
- package/dist/server/bare/addons/whispercpp-transcription/index.d.ts +0 -3
- package/dist/server/bare/addons/whispercpp-transcription/index.js +0 -2
- /package/dist/models/{hyperdrive → registry}/index.d.ts +0 -0
- /package/dist/server/bare/{addons → ops}/cancel.d.ts +0 -0
- /package/dist/server/bare/{addons → ops}/cancel.js +0 -0
- /package/dist/server/bare/{addons/llamacpp-completion → ops}/kv-cache-utils.d.ts +0 -0
- /package/dist/server/bare/{addons → ops}/load-model.d.ts +0 -0
- /package/dist/server/bare/{addons → ops}/unload-model.d.ts +0 -0
- /package/dist/server/bare/{addons → ops}/unload-model.js +0 -0
- /package/dist/server/bare/{addons/llamacpp-completion → plugins/llamacpp-completion/ops}/cache-logger.d.ts +0 -0
- /package/dist/server/bare/{addons/onnx-ocr/handlers → plugins/onnx-ocr/ops}/ocr-stream.d.ts +0 -0
- /package/dist/server/bare/{addons/onnx-tts/handlers → plugins/onnx-tts/ops}/text-to-speech.d.ts +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import { modelSrcInputSchema } from "./model-src-utils.js";
|
|
2
3
|
// TTS supported languages based on available models
|
|
3
4
|
export const TTS_LANGUAGES = [
|
|
4
5
|
"en", // English
|
|
@@ -6,13 +7,61 @@ export const TTS_LANGUAGES = [
|
|
|
6
7
|
"de", // German
|
|
7
8
|
"it", // Italian
|
|
8
9
|
];
|
|
9
|
-
export const
|
|
10
|
+
export const ttsChatterboxConfigSchema = z.object({
|
|
11
|
+
ttsEngine: z.literal("chatterbox"),
|
|
10
12
|
language: z.enum(TTS_LANGUAGES),
|
|
13
|
+
ttsTokenizerSrc: modelSrcInputSchema,
|
|
14
|
+
ttsSpeechEncoderSrc: modelSrcInputSchema,
|
|
15
|
+
ttsEmbedTokensSrc: modelSrcInputSchema,
|
|
16
|
+
ttsConditionalDecoderSrc: modelSrcInputSchema,
|
|
17
|
+
ttsLanguageModelSrc: modelSrcInputSchema,
|
|
18
|
+
referenceAudioSrc: modelSrcInputSchema,
|
|
11
19
|
});
|
|
20
|
+
export const ttsSupertonicConfigSchema = z.object({
|
|
21
|
+
ttsEngine: z.literal("supertonic"),
|
|
22
|
+
language: z.enum(TTS_LANGUAGES),
|
|
23
|
+
ttsTokenizerSrc: modelSrcInputSchema,
|
|
24
|
+
ttsTextEncoderSrc: modelSrcInputSchema,
|
|
25
|
+
ttsLatentDenoiserSrc: modelSrcInputSchema,
|
|
26
|
+
ttsVoiceDecoderSrc: modelSrcInputSchema,
|
|
27
|
+
ttsVoiceSrc: modelSrcInputSchema,
|
|
28
|
+
ttsSpeed: z.number().optional(),
|
|
29
|
+
ttsNumInferenceSteps: z.number().optional(),
|
|
30
|
+
});
|
|
31
|
+
export const ttsConfigSchema = z.union([
|
|
32
|
+
ttsChatterboxConfigSchema,
|
|
33
|
+
ttsSupertonicConfigSchema,
|
|
34
|
+
]);
|
|
35
|
+
// Request-level schemas with string sources (after ModelSrcInput is resolved to string)
|
|
36
|
+
export const ttsChatterboxRequestConfigSchema = z.object({
|
|
37
|
+
ttsEngine: z.literal("chatterbox"),
|
|
38
|
+
language: z.enum(TTS_LANGUAGES),
|
|
39
|
+
ttsTokenizerSrc: z.string(),
|
|
40
|
+
ttsSpeechEncoderSrc: z.string(),
|
|
41
|
+
ttsEmbedTokensSrc: z.string(),
|
|
42
|
+
ttsConditionalDecoderSrc: z.string(),
|
|
43
|
+
ttsLanguageModelSrc: z.string(),
|
|
44
|
+
referenceAudioSrc: z.string(),
|
|
45
|
+
});
|
|
46
|
+
export const ttsSupertonicRequestConfigSchema = z.object({
|
|
47
|
+
ttsEngine: z.literal("supertonic"),
|
|
48
|
+
language: z.enum(TTS_LANGUAGES),
|
|
49
|
+
ttsTokenizerSrc: z.string(),
|
|
50
|
+
ttsTextEncoderSrc: z.string(),
|
|
51
|
+
ttsLatentDenoiserSrc: z.string(),
|
|
52
|
+
ttsVoiceDecoderSrc: z.string(),
|
|
53
|
+
ttsVoiceSrc: z.string(),
|
|
54
|
+
ttsSpeed: z.number().optional(),
|
|
55
|
+
ttsNumInferenceSteps: z.number().optional(),
|
|
56
|
+
});
|
|
57
|
+
export const ttsRequestConfigSchema = z.union([
|
|
58
|
+
ttsChatterboxRequestConfigSchema,
|
|
59
|
+
ttsSupertonicRequestConfigSchema,
|
|
60
|
+
]);
|
|
12
61
|
export const ttsClientParamsSchema = z.object({
|
|
13
62
|
modelId: z.string(),
|
|
14
63
|
inputType: z.string().default("text"),
|
|
15
|
-
text: z.string(),
|
|
64
|
+
text: z.string().trim().min(1, "text must not be empty or whitespace-only"),
|
|
16
65
|
stream: z.boolean().default(true),
|
|
17
66
|
});
|
|
18
67
|
export const ttsRequestSchema = ttsClientParamsSchema.extend({
|
|
@@ -67,12 +67,12 @@ export declare const translateServerParamsSchema: z.ZodPipe<z.ZodUnion<readonly
|
|
|
67
67
|
to: z.ZodString;
|
|
68
68
|
context: z.ZodOptional<z.ZodString>;
|
|
69
69
|
}, z.core.$strip>]>, z.ZodTransform<{
|
|
70
|
-
modelType:
|
|
70
|
+
modelType: string;
|
|
71
71
|
modelId: string;
|
|
72
72
|
text: string | string[];
|
|
73
73
|
stream: boolean;
|
|
74
74
|
} | {
|
|
75
|
-
modelType:
|
|
75
|
+
modelType: string;
|
|
76
76
|
modelId: string;
|
|
77
77
|
text: string;
|
|
78
78
|
stream: boolean;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { readdirSync, existsSync, readFileSync, writeFileSync } from "fs";
|
|
2
|
+
import { join, dirname, relative } from "path";
|
|
3
|
+
import { spawnSync } from "child_process";
|
|
4
|
+
import { fileURLToPath } from "url";
|
|
5
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
const pkgRoot = join(__dirname, "..");
|
|
7
|
+
const testDistRoot = join(pkgRoot, "test", "dist");
|
|
8
|
+
const testDistDir = join(testDistRoot, "test", "unit");
|
|
9
|
+
// Step 1: Compile
|
|
10
|
+
console.log("Compiling tests...");
|
|
11
|
+
spawnSync("rm", ["-rf", testDistRoot], { cwd: pkgRoot });
|
|
12
|
+
const compile = spawnSync("tsc", ["--project", join(pkgRoot, "test", "tsconfig.json")], {
|
|
13
|
+
stdio: "inherit",
|
|
14
|
+
cwd: pkgRoot,
|
|
15
|
+
});
|
|
16
|
+
// tsc exits non-zero for pre-existing issues in other test files (unused @ts-expect-error,
|
|
17
|
+
// index signature access, etc.) but emits JS via noEmitOnError: false — verify output exists
|
|
18
|
+
if (compile.status !== 0 && !existsSync(testDistDir)) {
|
|
19
|
+
console.error("Test compilation failed — no output produced");
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
// Step 2: Resolve @/ aliases in compiled output
|
|
23
|
+
function walk(dir) {
|
|
24
|
+
const results = [];
|
|
25
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
26
|
+
const full = join(dir, entry.name);
|
|
27
|
+
if (entry.isDirectory())
|
|
28
|
+
results.push(...walk(full));
|
|
29
|
+
else if (entry.name.endsWith(".js"))
|
|
30
|
+
results.push(full);
|
|
31
|
+
}
|
|
32
|
+
return results;
|
|
33
|
+
}
|
|
34
|
+
function resolveTarget(fromFile, spec) {
|
|
35
|
+
const target = join(testDistRoot, spec);
|
|
36
|
+
let rel = relative(dirname(fromFile), target).split("\\").join("/");
|
|
37
|
+
if (!rel.startsWith("."))
|
|
38
|
+
rel = `./${rel}`;
|
|
39
|
+
if (existsSync(`${target}.js`))
|
|
40
|
+
return `${rel}.js`;
|
|
41
|
+
if (existsSync(join(target, "index.js")))
|
|
42
|
+
return `${rel}/index.js`;
|
|
43
|
+
return `${rel}.js`;
|
|
44
|
+
}
|
|
45
|
+
for (const file of walk(testDistRoot)) {
|
|
46
|
+
const content = readFileSync(file, "utf-8");
|
|
47
|
+
let updated = content;
|
|
48
|
+
// Static imports/exports: from "../....js"
|
|
49
|
+
updated = updated.replace(/((?:from|import)\s*["'])@\/([^"']+)(["'])/g, (_m, pre, spec, suf) => `${pre}${resolveTarget(file, spec)}${suf}`);
|
|
50
|
+
// Dynamic imports: import("../....js")
|
|
51
|
+
updated = updated.replace(/(import\s*\(\s*["'])@\/([^"']+)(["']\s*\))/g, (_m, pre, spec, suf) => `${pre}${resolveTarget(file, spec)}${suf}`);
|
|
52
|
+
if (updated !== content)
|
|
53
|
+
writeFileSync(file, updated);
|
|
54
|
+
}
|
|
55
|
+
// Step 3: Run under Bare
|
|
56
|
+
if (!existsSync(testDistDir)) {
|
|
57
|
+
console.error(`Test dist not found: ${testDistDir}`);
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
const testFiles = readdirSync(testDistDir).filter((f) => (f.startsWith("path-traversal") || f.startsWith("path-security")) &&
|
|
61
|
+
f.endsWith(".test.js"));
|
|
62
|
+
if (testFiles.length === 0) {
|
|
63
|
+
console.log("No compiled security test files found.");
|
|
64
|
+
process.exit(0);
|
|
65
|
+
}
|
|
66
|
+
const brittleBare = join(pkgRoot, "node_modules", ".bin", "brittle-bare");
|
|
67
|
+
let hasFailure = false;
|
|
68
|
+
for (const file of testFiles) {
|
|
69
|
+
const testPath = relative(pkgRoot, join(testDistDir, file));
|
|
70
|
+
console.log(`\nRunning under Bare: ${file}`);
|
|
71
|
+
const result = spawnSync(brittleBare, [testPath], {
|
|
72
|
+
stdio: "inherit",
|
|
73
|
+
cwd: pkgRoot,
|
|
74
|
+
});
|
|
75
|
+
if (result.status !== 0)
|
|
76
|
+
hasFailure = true;
|
|
77
|
+
}
|
|
78
|
+
process.exit(hasFailure ? 1 : 0);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { readdirSync } from "fs";
|
|
2
|
+
import { join, dirname } from "path";
|
|
3
|
+
import { spawnSync } from "child_process";
|
|
4
|
+
import { fileURLToPath } from "url";
|
|
5
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
const testDir = join(__dirname, "..", "test", "unit");
|
|
7
|
+
const testFiles = readdirSync(testDir).filter((f) => (f.startsWith("path-traversal") || f.startsWith("path-security")) &&
|
|
8
|
+
f.endsWith(".test.ts"));
|
|
9
|
+
if (testFiles.length === 0) {
|
|
10
|
+
console.log("No security tests found.");
|
|
11
|
+
process.exit(0);
|
|
12
|
+
}
|
|
13
|
+
let hasFailure = false;
|
|
14
|
+
for (const file of testFiles) {
|
|
15
|
+
const result = spawnSync("bun", ["run", join(testDir, file)], {
|
|
16
|
+
stdio: "inherit",
|
|
17
|
+
});
|
|
18
|
+
if (result.status !== 0) {
|
|
19
|
+
hasFailure = true;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
process.exit(hasFailure ? 1 : 0);
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import RPC from "bare-rpc";
|
|
2
2
|
import type { RPCOptions } from "../../schemas/index";
|
|
3
3
|
export declare function getRPC(topic: string, publicKey: string, options?: RPCOptions): Promise<RPC>;
|
|
4
|
+
/**
|
|
5
|
+
* Remove a stale RPC connection for a peer.
|
|
6
|
+
* Called when a delegation request fails (e.g., timeout) so the next
|
|
7
|
+
* attempt creates a fresh connection instead of reusing a dead RPC.
|
|
8
|
+
*/
|
|
9
|
+
export declare function cleanupStaleConnection(publicKey: string): void;
|
|
4
10
|
//# sourceMappingURL=delegate-rpc-client.d.ts.map
|
|
@@ -8,67 +8,23 @@ const logger = getServerLogger();
|
|
|
8
8
|
const activeRPCs = new Map();
|
|
9
9
|
// Map to store underlying connections for cleanup
|
|
10
10
|
const activeConnections = new Map();
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
// Check if we already have an RPC instance for this peer
|
|
23
|
-
let rpc = activeRPCs.get(publicKey);
|
|
11
|
+
// Track whether the global connection handler has been registered
|
|
12
|
+
let connectionHandlerRegistered = false;
|
|
13
|
+
/**
|
|
14
|
+
* Register the swarm "connection" handler once (not per getRPC call).
|
|
15
|
+
* This fixes the event listener leak where each getRPC() call added
|
|
16
|
+
* a new listener, causing duplicate RPC instances on the same stream.
|
|
17
|
+
*/
|
|
18
|
+
function ensureConnectionHandler() {
|
|
19
|
+
if (connectionHandlerRegistered)
|
|
20
|
+
return;
|
|
21
|
+
connectionHandlerRegistered = true;
|
|
24
22
|
const swarm = getSwarm();
|
|
25
|
-
if (!rpc) {
|
|
26
|
-
// Need to establish connection first
|
|
27
|
-
try {
|
|
28
|
-
logger.info(`🔗 Establishing RPC connection to topic: ${topic}, peer: ${publicKey}, timeout: ${timeout}ms`);
|
|
29
|
-
const connectionPromise = (async () => {
|
|
30
|
-
const topicBuffer = Buffer.from(topic, "hex");
|
|
31
|
-
// const discovery =
|
|
32
|
-
swarm.join(topicBuffer, {
|
|
33
|
-
server: false,
|
|
34
|
-
client: true,
|
|
35
|
-
});
|
|
36
|
-
await swarm.flush();
|
|
37
|
-
logger.info(`✅ Connected to topic: ${topic}`);
|
|
38
|
-
logger.debug(`📊 Active RPC connections: ${activeRPCs.size}`);
|
|
39
|
-
// Check again if we now have an RPC instance for the target peer
|
|
40
|
-
rpc = activeRPCs.get(publicKey);
|
|
41
|
-
if (!rpc) {
|
|
42
|
-
logger.error(`❌ No RPC instance found for peer ${publicKey}`);
|
|
43
|
-
logger.debug(`📊 Available RPC connections:`, Array.from(activeRPCs.keys()));
|
|
44
|
-
throw new DelegateConnectionFailedError(`Could not establish RPC connection to peer ${publicKey} on topic ${topic}`);
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
logger.debug(`✅ RPC instance found for peer ${publicKey}`);
|
|
48
|
-
}
|
|
49
|
-
})();
|
|
50
|
-
await withTimeout(connectionPromise, timeout);
|
|
51
|
-
}
|
|
52
|
-
catch (error) {
|
|
53
|
-
logger.error("Failed to establish RPC connection:", error);
|
|
54
|
-
throw new DelegateConnectionFailedError(`RPC connection failed: ${error instanceof Error ? error.message : String(error)}`, error);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
return rpc;
|
|
58
|
-
}
|
|
59
|
-
// Create an RPC instance for a specific HyperSwarm peer
|
|
60
|
-
export async function getRPC(topic, publicKey, options = {}) {
|
|
61
|
-
const swarm = getSwarm();
|
|
62
|
-
// Close existing connection if forceNewConnection is true
|
|
63
|
-
if (options.forceNewConnection) {
|
|
64
|
-
closeConnection(publicKey);
|
|
65
|
-
}
|
|
66
|
-
// Set up connection tracking
|
|
67
23
|
swarm.on("connection", (conn) => {
|
|
68
24
|
const peerPubkey = conn.remotePublicKey?.toString("hex");
|
|
69
25
|
if (!peerPubkey)
|
|
70
26
|
return;
|
|
71
|
-
logger.
|
|
27
|
+
logger.info(`🍺 New peer connection established: ${peerPubkey}`);
|
|
72
28
|
// Create RPC instance for this connection (as client)
|
|
73
29
|
const rpc = new RPC(conn, () => {
|
|
74
30
|
// No-op handler since we're only sending requests, not receiving them
|
|
@@ -87,5 +43,129 @@ export async function getRPC(topic, publicKey, options = {}) {
|
|
|
87
43
|
activeConnections.delete(peerPubkey);
|
|
88
44
|
});
|
|
89
45
|
});
|
|
46
|
+
}
|
|
47
|
+
async function closeConnection(publicKey) {
|
|
48
|
+
const existingConnection = activeConnections.get(publicKey);
|
|
49
|
+
if (existingConnection) {
|
|
50
|
+
logger.info(`🔌 Closing existing connection for peer: ${publicKey}`);
|
|
51
|
+
// Wait for the close event before returning so Hyperswarm's internal
|
|
52
|
+
// _allConnections is cleaned up before we attempt to rejoin/flush.
|
|
53
|
+
await new Promise((resolve) => {
|
|
54
|
+
const timeout = setTimeout(resolve, 5000);
|
|
55
|
+
existingConnection.on("close", () => {
|
|
56
|
+
clearTimeout(timeout);
|
|
57
|
+
resolve();
|
|
58
|
+
});
|
|
59
|
+
existingConnection.destroy();
|
|
60
|
+
});
|
|
61
|
+
activeConnections.delete(publicKey);
|
|
62
|
+
activeRPCs.delete(publicKey);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Establish RPC connection to a peer if not already connected
|
|
66
|
+
async function ensureRPCConnection(topic, publicKey, timeout) {
|
|
67
|
+
// Check if we already have an RPC instance for this peer
|
|
68
|
+
const existingRpc = activeRPCs.get(publicKey);
|
|
69
|
+
if (existingRpc) {
|
|
70
|
+
return existingRpc;
|
|
71
|
+
}
|
|
72
|
+
const swarm = getSwarm();
|
|
73
|
+
// Track the listener so we can clean it up on timeout
|
|
74
|
+
let onConnection = () => { };
|
|
75
|
+
try {
|
|
76
|
+
logger.info(`🔗 Establishing RPC connection to topic: ${topic}, peer: ${publicKey}, timeout: ${timeout}ms`);
|
|
77
|
+
const connectionPromise = new Promise((resolve, reject) => {
|
|
78
|
+
const topicBuffer = Buffer.from(topic, "hex");
|
|
79
|
+
swarm.join(topicBuffer, {
|
|
80
|
+
server: false,
|
|
81
|
+
client: true,
|
|
82
|
+
});
|
|
83
|
+
// Wait for the specific peer's connection event instead of just
|
|
84
|
+
// checking after flush. This handles the case where flush resolves
|
|
85
|
+
// (discovery done) but the P2P connection is still being established
|
|
86
|
+
// via holepunching or relays.
|
|
87
|
+
onConnection = (conn) => {
|
|
88
|
+
const peerPubkey = conn.remotePublicKey?.toString("hex");
|
|
89
|
+
if (peerPubkey === publicKey) {
|
|
90
|
+
swarm.removeListener("connection", onConnection);
|
|
91
|
+
// The global handler (ensureConnectionHandler) will create the RPC
|
|
92
|
+
// and store it in activeRPCs. Give it a tick to run first.
|
|
93
|
+
const rpc = activeRPCs.get(publicKey);
|
|
94
|
+
if (rpc) {
|
|
95
|
+
resolve(rpc);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
// Global handler runs synchronously before us in the same event,
|
|
99
|
+
// so this shouldn't happen, but handle it just in case
|
|
100
|
+
setTimeout(() => {
|
|
101
|
+
const delayedRpc = activeRPCs.get(publicKey);
|
|
102
|
+
if (delayedRpc) {
|
|
103
|
+
resolve(delayedRpc);
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
reject(new DelegateConnectionFailedError(`Connection established but RPC not created for peer ${publicKey}`));
|
|
107
|
+
}
|
|
108
|
+
}, 100);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
swarm.on("connection", onConnection);
|
|
113
|
+
// Also flush to trigger discovery. After flush, check if the connection
|
|
114
|
+
// was already established (the global handler may have caught it).
|
|
115
|
+
void swarm.flush().then(() => {
|
|
116
|
+
logger.info(`✅ Flush completed for topic: ${topic}`);
|
|
117
|
+
logger.debug(`📊 Active RPC connections: ${activeRPCs.size}`);
|
|
118
|
+
const rpc = activeRPCs.get(publicKey);
|
|
119
|
+
if (rpc) {
|
|
120
|
+
swarm.removeListener("connection", onConnection);
|
|
121
|
+
resolve(rpc);
|
|
122
|
+
}
|
|
123
|
+
// If not connected after flush, the onConnection listener keeps
|
|
124
|
+
// waiting until the timeout from withTimeout kicks in.
|
|
125
|
+
// Hyperswarm may still establish the connection via retries/relays.
|
|
126
|
+
logger.debug(`⏳ Peer not connected after flush, waiting for connection event...`);
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
return await withTimeout(connectionPromise, timeout);
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
// Clean up the per-request connection listener
|
|
133
|
+
swarm.removeListener("connection", onConnection);
|
|
134
|
+
// Remove stale connection so next attempt creates a fresh one
|
|
135
|
+
// instead of reusing a dead RPC
|
|
136
|
+
logger.info(`🗑️ Removing stale connection for peer: ${publicKey} after failed RPC attempt`);
|
|
137
|
+
activeRPCs.delete(publicKey);
|
|
138
|
+
const conn = activeConnections.get(publicKey);
|
|
139
|
+
if (conn) {
|
|
140
|
+
conn.destroy();
|
|
141
|
+
activeConnections.delete(publicKey);
|
|
142
|
+
}
|
|
143
|
+
logger.error("Failed to establish RPC connection:", error);
|
|
144
|
+
throw new DelegateConnectionFailedError(`RPC connection failed: ${error instanceof Error ? error.message : String(error)}`, error);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
// Create an RPC instance for a specific HyperSwarm peer
|
|
148
|
+
export async function getRPC(topic, publicKey, options = {}) {
|
|
149
|
+
// Ensure the global connection handler is registered (once)
|
|
150
|
+
ensureConnectionHandler();
|
|
151
|
+
// Close existing connection if forceNewConnection is true
|
|
152
|
+
// Await the close to avoid racing with the subsequent join/flush
|
|
153
|
+
if (options.forceNewConnection) {
|
|
154
|
+
await closeConnection(publicKey);
|
|
155
|
+
}
|
|
90
156
|
return await ensureRPCConnection(topic, publicKey, options.timeout);
|
|
91
157
|
}
|
|
158
|
+
/**
|
|
159
|
+
* Remove a stale RPC connection for a peer.
|
|
160
|
+
* Called when a delegation request fails (e.g., timeout) so the next
|
|
161
|
+
* attempt creates a fresh connection instead of reusing a dead RPC.
|
|
162
|
+
*/
|
|
163
|
+
export function cleanupStaleConnection(publicKey) {
|
|
164
|
+
logger.info(`🗑️ Removing stale connection for peer: ${publicKey} after failed delegation`);
|
|
165
|
+
activeRPCs.delete(publicKey);
|
|
166
|
+
const conn = activeConnections.get(publicKey);
|
|
167
|
+
if (conn) {
|
|
168
|
+
conn.destroy();
|
|
169
|
+
activeConnections.delete(publicKey);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { getModel } from "
|
|
2
|
-
import { embedParamsSchema } from "
|
|
3
|
-
import { EmbedNoEmbeddingsError, EmbedFailedError, } from "
|
|
1
|
+
import { getModel } from "../registry/model-registry.js";
|
|
2
|
+
import { embedParamsSchema } from "../../../schemas/index.js";
|
|
3
|
+
import { EmbedNoEmbeddingsError, EmbedFailedError, } from "../../../utils/errors-server.js";
|
|
4
4
|
export async function embed(params) {
|
|
5
5
|
const { modelId, text } = embedParamsSchema.parse(params);
|
|
6
6
|
const model = getModel(modelId);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import crypto from "bare-crypto";
|
|
2
2
|
import { promises as fsPromises } from "bare-fs";
|
|
3
3
|
import path from "bare-path";
|
|
4
|
-
import { getKVCacheDir } from "
|
|
5
|
-
import { getServerLogger } from "
|
|
4
|
+
import { getKVCacheDir, validateAndJoinPath } from "../../utils/index.js";
|
|
5
|
+
import { getServerLogger } from "../../../logging/index.js";
|
|
6
6
|
const logger = getServerLogger();
|
|
7
7
|
// In-memory registry tracks caches initialized this session (addon defers disk writes)
|
|
8
8
|
const initializedCaches = new Set();
|
|
@@ -57,8 +57,8 @@ export function generateCacheKey(messages) {
|
|
|
57
57
|
}
|
|
58
58
|
export async function getCacheFilePath(modelId, configHash, cacheKey) {
|
|
59
59
|
const cacheDir = getKVCacheDir();
|
|
60
|
-
const sessionCacheDir =
|
|
61
|
-
const modelCacheDir =
|
|
60
|
+
const sessionCacheDir = validateAndJoinPath(cacheDir, cacheKey);
|
|
61
|
+
const modelCacheDir = validateAndJoinPath(sessionCacheDir, modelId);
|
|
62
62
|
try {
|
|
63
63
|
await fsPromises.mkdir(sessionCacheDir, { recursive: true });
|
|
64
64
|
await fsPromises.mkdir(modelCacheDir, { recursive: true });
|
|
@@ -126,9 +126,9 @@ export async function deleteCache(options) {
|
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
128
|
else if ("kvCacheKey" in options) {
|
|
129
|
-
const kvCacheDir =
|
|
129
|
+
const kvCacheDir = validateAndJoinPath(cacheDir, options.kvCacheKey);
|
|
130
130
|
if (options.modelId) {
|
|
131
|
-
const modelCacheDir =
|
|
131
|
+
const modelCacheDir = validateAndJoinPath(kvCacheDir, options.modelId);
|
|
132
132
|
try {
|
|
133
133
|
await fsPromises.rm(modelCacheDir, { recursive: true });
|
|
134
134
|
}
|
|
@@ -1,21 +1,18 @@
|
|
|
1
|
-
import { loadModelServerParamsSchema, ModelType, } from "../../../schemas/index.js";
|
|
2
|
-
import { createLlmModel } from "./llamacpp-completion/index.js";
|
|
3
|
-
import { createEmbeddingsModel } from "./llamacpp-embedding/index.js";
|
|
4
|
-
import { createNmtModel } from "./nmtcpp-translation/index.js";
|
|
5
|
-
import { createTtsModel } from "./onnx-tts/index.js";
|
|
6
|
-
import { createWhisperModel } from "./whispercpp-transcription/index.js";
|
|
7
|
-
import { createOCRModel } from "./onnx-ocr/index.js";
|
|
1
|
+
import { loadModelServerParamsSchema, ModelType, normalizeModelType, } from "../../../schemas/index.js";
|
|
8
2
|
import { isModelLoaded, registerModel, } from "../registry/model-registry.js";
|
|
9
3
|
import { startLogBuffering, stopLogBufferingWithTimeout, } from "../registry/logging-stream-registry.js";
|
|
10
4
|
import { detectShardedModel, generateShardFilenames, validateShardedModelCache, } from "../../utils/index.js";
|
|
11
|
-
import {
|
|
5
|
+
import { ModelLoadFailedError, PluginNotFoundError, ModelFileNotFoundError, ModelFileNotFoundInDirError, ModelFileLocateFailedError, } from "../../../utils/errors-server.js";
|
|
6
|
+
import { getPlugin } from "../../plugins/index.js";
|
|
12
7
|
import { promises as fsPromises } from "bare-fs";
|
|
13
8
|
import path from "bare-path";
|
|
14
9
|
import { getServerLogger } from "../../../logging/index.js";
|
|
15
10
|
const logger = getServerLogger();
|
|
16
11
|
export async function loadModel(params) {
|
|
17
|
-
const { modelId, modelPath, options, projectionModelPath, vadModelPath,
|
|
18
|
-
const { modelConfig, modelType } = options;
|
|
12
|
+
const { modelId, modelPath, options, projectionModelPath, vadModelPath, detectorModelPath, modelName, } = loadModelServerParamsSchema.parse(params);
|
|
13
|
+
const { modelConfig, modelType: rawModelType } = options;
|
|
14
|
+
// Normalize modelType to canonical form (handles aliases and custom types)
|
|
15
|
+
const modelType = normalizeModelType(rawModelType);
|
|
19
16
|
// Check if model is already loaded
|
|
20
17
|
if (isModelLoaded(modelId)) {
|
|
21
18
|
logger.info(`${modelType} model ${modelId} is already loaded`);
|
|
@@ -34,8 +31,9 @@ export async function loadModel(params) {
|
|
|
34
31
|
throw new ModelFileNotFoundError(`Missing shards or ${shardInfo.baseFilename}.tensors.txt. Expected ${numberedShards.length} shard files + tensors.txt in ${shardDir}`);
|
|
35
32
|
}
|
|
36
33
|
}
|
|
37
|
-
else {
|
|
34
|
+
else if (modelType !== ModelType.onnxTts) {
|
|
38
35
|
// For non-sharded models, validate single file exists
|
|
36
|
+
// Skip for TTS - it uses multiple paths from modelConfig (resolved by plugin.resolveConfig)
|
|
39
37
|
try {
|
|
40
38
|
const modelDir = path.dirname(modelPath);
|
|
41
39
|
const modelFile = path.basename(modelPath);
|
|
@@ -49,37 +47,29 @@ export async function loadModel(params) {
|
|
|
49
47
|
throw new ModelFileLocateFailedError(modelType, modelPath, error);
|
|
50
48
|
}
|
|
51
49
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
case ModelType.llamacppCompletion:
|
|
55
|
-
result = createLlmModel(modelId, modelPath, modelConfig, projectionModelPath);
|
|
56
|
-
break;
|
|
57
|
-
case ModelType.whispercppTranscription:
|
|
58
|
-
result = createWhisperModel(modelId, modelPath, modelConfig, vadModelPath);
|
|
59
|
-
break;
|
|
60
|
-
case ModelType.llamacppEmbedding:
|
|
61
|
-
result = createEmbeddingsModel(modelId, modelPath, modelConfig);
|
|
62
|
-
break;
|
|
63
|
-
case ModelType.nmtcppTranslation:
|
|
64
|
-
result = createNmtModel(modelId, modelPath, modelConfig);
|
|
65
|
-
break;
|
|
66
|
-
case ModelType.onnxTts:
|
|
67
|
-
if (!eSpeakDataPath) {
|
|
68
|
-
throw new ESpeakDataPathRequiredError();
|
|
69
|
-
}
|
|
70
|
-
result = createTtsModel(modelId, modelPath, modelConfig, ttsConfigModelPath, eSpeakDataPath);
|
|
71
|
-
break;
|
|
72
|
-
case ModelType.onnxOcr:
|
|
73
|
-
if (!detectorModelPath) {
|
|
74
|
-
throw new ModelLoadFailedError("Detector model required for OCR. Use a hyperdrive source or provide detectorModelSrc");
|
|
75
|
-
}
|
|
76
|
-
// modelPath is the recognizer, detectorModelPath is auto-derived
|
|
77
|
-
result = createOCRModel(modelId, detectorModelPath, modelPath, modelConfig);
|
|
78
|
-
break;
|
|
79
|
-
default:
|
|
80
|
-
// Should never happen - normalizeModelType validates input
|
|
81
|
-
throw new UnknownModelTypeError(modelType);
|
|
50
|
+
if (modelType === ModelType.onnxOcr && !detectorModelPath) {
|
|
51
|
+
throw new ModelLoadFailedError("Detector model required for OCR. Use a hyperdrive source or provide detectorModelSrc");
|
|
82
52
|
}
|
|
53
|
+
const plugin = getPlugin(modelType);
|
|
54
|
+
if (!plugin) {
|
|
55
|
+
throw new PluginNotFoundError(modelType);
|
|
56
|
+
}
|
|
57
|
+
// Build artifacts map for plugin
|
|
58
|
+
// Note: TTS paths are in modelConfig (resolved by plugin.resolveConfig), not artifacts
|
|
59
|
+
const artifacts = {};
|
|
60
|
+
if (projectionModelPath)
|
|
61
|
+
artifacts["projectionModelPath"] = projectionModelPath;
|
|
62
|
+
if (vadModelPath)
|
|
63
|
+
artifacts["vadModelPath"] = vadModelPath;
|
|
64
|
+
if (detectorModelPath)
|
|
65
|
+
artifacts["detectorModelPath"] = detectorModelPath;
|
|
66
|
+
const result = plugin.createModel({
|
|
67
|
+
modelId,
|
|
68
|
+
modelPath,
|
|
69
|
+
modelConfig: modelConfig,
|
|
70
|
+
modelName,
|
|
71
|
+
artifacts: Object.keys(artifacts).length > 0 ? artifacts : undefined,
|
|
72
|
+
});
|
|
83
73
|
logger.info(`${modelType}: Loading model ${modelId}...`);
|
|
84
74
|
startLogBuffering(modelId);
|
|
85
75
|
await result.model.load(false);
|
|
@@ -89,7 +79,7 @@ export async function loadModel(params) {
|
|
|
89
79
|
model: result.model,
|
|
90
80
|
path: modelPath,
|
|
91
81
|
config: modelConfig,
|
|
92
|
-
modelType,
|
|
82
|
+
modelType: modelType,
|
|
93
83
|
name: modelName,
|
|
94
84
|
loader: result.loader,
|
|
95
85
|
});
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { type TranslateParams, type TranslationStats } from "
|
|
1
|
+
import { type TranslateParams, type TranslationStats } from "../../../schemas/index";
|
|
2
2
|
export declare function translate(params: TranslateParams): AsyncGenerator<string, TranslationStats | undefined, unknown>;
|
|
3
3
|
//# sourceMappingURL=translate.d.ts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { getModel } from "
|
|
2
|
-
import { translateServerParamsSchema, normalizeModelType, ModelType, } from "
|
|
1
|
+
import { getModel } from "../registry/model-registry.js";
|
|
2
|
+
import { translateServerParamsSchema, normalizeModelType, ModelType, } from "../../../schemas/index.js";
|
|
3
3
|
import { getLangName } from "@qvac/langdetect-text";
|
|
4
4
|
function getLanguage(code) {
|
|
5
5
|
if (!code)
|
|
@@ -26,10 +26,11 @@ export async function* translate(params) {
|
|
|
26
26
|
// Use runBatch for batch processing
|
|
27
27
|
const translations = await model.runBatch(text);
|
|
28
28
|
// Yield each translation with a newline separator
|
|
29
|
-
for (
|
|
29
|
+
for (let i = 0; i < translations.length; i++) {
|
|
30
|
+
const translation = translations[i];
|
|
30
31
|
processedTokens++;
|
|
31
32
|
yield translation;
|
|
32
|
-
if (
|
|
33
|
+
if (i < translations.length - 1) {
|
|
33
34
|
yield "\n";
|
|
34
35
|
}
|
|
35
36
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { llmPlugin } from "./llamacpp-completion/plugin";
|
|
2
|
+
export { embeddingsPlugin } from "./llamacpp-embedding/plugin";
|
|
3
|
+
export { whisperPlugin } from "./whispercpp-transcription/plugin";
|
|
4
|
+
export { nmtPlugin } from "./nmtcpp-translation/plugin";
|
|
5
|
+
export { ttsPlugin } from "./onnx-tts/plugin";
|
|
6
|
+
export { ocrPlugin } from "./onnx-ocr/plugin";
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { llmPlugin } from "./llamacpp-completion/plugin.js";
|
|
2
|
+
export { embeddingsPlugin } from "./llamacpp-embedding/plugin.js";
|
|
3
|
+
export { whisperPlugin } from "./whispercpp-transcription/plugin.js";
|
|
4
|
+
export { nmtPlugin } from "./nmtcpp-translation/plugin.js";
|
|
5
|
+
export { ttsPlugin } from "./onnx-tts/plugin.js";
|
|
6
|
+
export { ocrPlugin } from "./onnx-ocr/plugin.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { CompletionParams, CompletionStats, Tool, ToolCall, ToolCallEvent } from "../../../../../schemas/index";
|
|
2
2
|
export declare function completion(params: CompletionParams & {
|
|
3
3
|
tools?: Tool[];
|
|
4
4
|
}): AsyncGenerator<{
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {} from "
|
|
2
|
-
import {
|
|
3
|
-
import { customCacheExists, extractSystemPrompt, findMatchingCache, generateConfigHash, getCacheFilePath, getCurrentCacheInfo, markCacheInitialized, renameCacheFile, } from "../kv-cache-utils.js";
|
|
1
|
+
import { logCacheDisabled, logCacheInit, logCacheSave, logCacheStatus, logMessagesToAddon, } from "./cache-logger.js";
|
|
2
|
+
import { customCacheExists, extractSystemPrompt, findMatchingCache, generateConfigHash, getCacheFilePath, getCurrentCacheInfo, markCacheInitialized, renameCacheFile, } from "../../../ops/kv-cache-utils.js";
|
|
4
3
|
import { getModel, getModelConfig, } from "../../../registry/model-registry.js";
|
|
5
4
|
import { checkForToolEvents, insertToolsIntoHistory, setupToolGrammar, } from "../../../../utils/tool-integration.js";
|
|
6
5
|
import { parseToolCalls } from "../../../../utils/tool-parser.js";
|