@qvac/sdk 0.2.7-dev.1761566029.f834aa3 → 0.4.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/README.md +26 -3
- package/dist/client/api/cancel.d.ts +1 -1
- package/dist/client/api/cancel.js +4 -3
- package/dist/client/api/completion-stream.d.ts +24 -32
- package/dist/client/api/completion-stream.js +142 -50
- package/dist/client/api/delete-cache.js +3 -2
- package/dist/client/api/download-asset.d.ts +3 -3
- package/dist/client/api/download-asset.js +12 -17
- package/dist/client/api/embed.d.ts +1 -1
- package/dist/client/api/embed.js +4 -3
- package/dist/client/api/get-model-info.d.ts +29 -0
- package/dist/client/api/get-model-info.js +14 -0
- package/dist/client/api/index.d.ts +4 -0
- package/dist/client/api/index.js +4 -0
- package/dist/client/api/load-model.d.ts +3 -3
- package/dist/client/api/load-model.js +13 -22
- package/dist/client/api/logging-stream.d.ts +1 -1
- package/dist/client/api/logging-stream.js +3 -2
- package/dist/client/api/ping.d.ts +1 -1
- package/dist/client/api/ping.js +3 -2
- package/dist/client/api/provide.d.ts +1 -1
- package/dist/client/api/provide.js +4 -3
- package/dist/client/api/rag.d.ts +3 -3
- package/dist/client/api/rag.js +13 -12
- package/dist/client/api/set-config.d.ts +7 -0
- package/dist/client/api/set-config.js +20 -0
- package/dist/client/api/stop-provider.d.ts +15 -0
- package/dist/client/api/stop-provider.js +25 -0
- package/dist/client/api/text-to-speech.d.ts +7 -0
- package/dist/client/api/text-to-speech.js +58 -0
- package/dist/client/api/transcribe.d.ts +4 -2
- package/dist/client/api/transcribe.js +9 -5
- package/dist/client/api/translate.d.ts +1 -1
- package/dist/client/api/translate.js +3 -2
- package/dist/client/api/unload-model.d.ts +5 -1
- package/dist/client/api/unload-model.js +14 -4
- package/dist/client/config-manager.d.ts +4 -0
- package/dist/client/config-manager.js +8 -0
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/init-hooks.d.ts +6 -0
- package/dist/client/init-hooks.js +37 -0
- package/dist/client/rpc/bare-client.d.ts +73 -0
- package/dist/client/rpc/bare-client.js +5 -4
- package/dist/client/rpc/bare-rpc-client.js +7 -3
- package/dist/client/rpc/expo-rpc-client.d.ts +1 -0
- package/dist/client/rpc/expo-rpc-client.js +9 -1
- package/dist/client/rpc/node-rpc-client.d.ts +1 -1
- package/dist/client/rpc/node-rpc-client.js +22 -9
- package/dist/client/rpc/rpc-client.d.ts +1 -0
- package/dist/client/rpc/rpc-client.js +27 -3
- package/dist/examples/cache-management.d.ts +2 -0
- package/dist/examples/cache-management.js +97 -0
- package/dist/examples/delegated-inference/consumer.js +2 -2
- package/dist/examples/download-with-blind-relays.d.ts +2 -0
- package/dist/examples/download-with-blind-relays.js +48 -0
- package/dist/examples/download-with-cancel.js +3 -4
- package/dist/examples/embed-hyperdrive.js +0 -1
- package/dist/examples/kv-cache-cleanup.js +0 -1
- package/dist/examples/kv-cache-custom-key.js +0 -1
- package/dist/examples/kv-cache-example.js +0 -1
- package/dist/examples/llamacpp-file-logging.js +0 -1
- package/dist/examples/llamacpp-filesystem.js +2 -2
- package/dist/examples/llamacpp-http.js +0 -1
- package/dist/examples/llamacpp-hyperdrive.js +0 -1
- package/dist/examples/llamacpp-multimodal.js +0 -1
- package/dist/examples/llamacpp-native-tools.js +118 -36
- package/dist/examples/llamacpp-sharded.d.ts +2 -0
- package/dist/examples/llamacpp-sharded.js +44 -0
- package/dist/examples/multi-model-demo.js +0 -1
- package/dist/examples/parallel-download.js +2 -2
- package/dist/examples/rag/rag-chromadb.js +0 -1
- package/dist/examples/rag/rag-hyperdb-workspaces.js +0 -1
- package/dist/examples/rag/rag-hyperdb.js +0 -1
- package/dist/examples/rag/rag-lancedb.js +0 -1
- package/dist/examples/rag/rag-sqlite.js +0 -1
- package/dist/examples/text-to-speech.d.ts +3 -0
- package/dist/examples/text-to-speech.js +137 -0
- package/dist/examples/translation/translation-indic.js +3 -1
- package/dist/examples/translation/translation-llm-context.js +0 -1
- package/dist/examples/translation/translation-llm.js +2 -2
- package/dist/examples/translation/translation-opus.js +3 -1
- package/dist/examples/translation/translation-stream.js +0 -1
- package/dist/examples/whispercpp-filesystem.js +32 -5
- package/dist/examples/whispercpp-microphone-record.js +9 -9
- package/dist/examples/whispercpp-prompt.d.ts +2 -0
- package/dist/examples/whispercpp-prompt.js +68 -0
- package/dist/expo/plugins/withMobileBundle.js +9 -3
- package/dist/index.d.ts +4 -2
- package/dist/index.js +4 -2
- package/dist/models/hyperdrive/models.d.ts +1924 -100
- package/dist/models/hyperdrive/models.js +2051 -105
- package/dist/schemas/common.d.ts +420 -58
- package/dist/schemas/common.js +12 -0
- package/dist/schemas/completion-stream.d.ts +26 -22
- package/dist/schemas/completion-stream.js +9 -23
- package/dist/schemas/download-asset.d.ts +77 -2
- package/dist/schemas/download-asset.js +15 -4
- package/dist/schemas/get-model-info.d.ts +100 -0
- package/dist/schemas/get-model-info.js +40 -0
- package/dist/schemas/index.d.ts +8 -0
- package/dist/schemas/index.js +8 -0
- package/dist/schemas/llamacpp-config.d.ts +2 -1
- package/dist/schemas/llamacpp-config.js +3 -4
- package/dist/schemas/load-model.d.ts +2316 -266
- package/dist/schemas/load-model.js +157 -10
- package/dist/schemas/model-src-utils.d.ts +98 -0
- package/dist/schemas/model-src-utils.js +31 -0
- package/dist/schemas/sdk-errors-client.d.ts +25 -0
- package/dist/schemas/sdk-errors-client.js +111 -0
- package/dist/schemas/sdk-errors-server.d.ts +55 -0
- package/dist/schemas/sdk-errors-server.js +271 -0
- package/dist/schemas/set-config.d.ts +21 -0
- package/dist/schemas/set-config.js +14 -0
- package/dist/schemas/stop-provide.d.ts +17 -0
- package/dist/schemas/stop-provide.js +15 -0
- package/dist/schemas/text-to-speech.d.ts +34 -0
- package/dist/schemas/text-to-speech.js +25 -0
- package/dist/schemas/tools.d.ts +62 -0
- package/dist/schemas/tools.js +43 -0
- package/dist/schemas/transcription.d.ts +25 -2
- package/dist/schemas/transcription.js +12 -1
- package/dist/schemas/translation-config.d.ts +33 -5
- package/dist/schemas/translation-config.js +18 -1
- package/dist/schemas/unload-model.d.ts +2 -0
- package/dist/schemas/unload-model.js +2 -0
- package/dist/schemas/whispercpp-config.d.ts +55 -18
- package/dist/schemas/whispercpp-config.js +63 -15
- package/dist/server/bare/addons/cancel.js +2 -1
- package/dist/server/bare/addons/llamacpp/create-model.d.ts +9 -2
- package/dist/server/bare/addons/llamacpp/create-model.js +23 -23
- package/dist/server/bare/addons/llamacpp/handlers/completion-stream.d.ts +10 -2
- package/dist/server/bare/addons/llamacpp/handlers/completion-stream.js +62 -43
- package/dist/server/bare/addons/llamacpp/handlers/embed.js +3 -2
- package/dist/server/bare/addons/llamacpp/kv-cache-utils.d.ts +1 -1
- package/dist/server/bare/addons/llamacpp/kv-cache-utils.js +6 -2
- package/dist/server/bare/addons/load-model.js +59 -28
- package/dist/server/bare/addons/translation/create-model.d.ts +5 -1
- package/dist/server/bare/addons/translation/create-model.js +17 -25
- package/dist/server/bare/addons/translation/handlers/translate.js +10 -1
- package/dist/server/bare/addons/tts/create-model.d.ts +10 -0
- package/dist/server/bare/addons/tts/create-model.js +25 -0
- package/dist/server/bare/addons/tts/handlers/text-to-speech.d.ts +3 -0
- package/dist/server/bare/addons/tts/handlers/text-to-speech.js +87 -0
- package/dist/server/bare/addons/tts/index.d.ts +3 -0
- package/dist/server/bare/addons/tts/index.js +2 -0
- package/dist/server/bare/addons/unload-model.js +21 -3
- package/dist/server/bare/addons/whispercpp/create-model.d.ts +5 -1
- package/dist/server/bare/addons/whispercpp/create-model.js +13 -32
- package/dist/server/bare/addons/whispercpp/handlers/transcribe-stream.js +41 -20
- package/dist/server/bare/delegate-rpc-client.js +3 -2
- package/dist/server/bare/hyperswarm.d.ts +3 -0
- package/dist/server/bare/hyperswarm.js +22 -1
- package/dist/server/bare/rag-hyperdb/rag-manager.js +16 -13
- package/dist/server/bare/registry/config-registry.d.ts +5 -0
- package/dist/server/bare/registry/config-registry.js +39 -0
- package/dist/server/bare/registry/logging-stream-registry.d.ts +1 -0
- package/dist/server/bare/registry/logging-stream-registry.js +7 -0
- package/dist/server/bare/registry/model-registry.d.ts +13 -0
- package/dist/server/bare/registry/model-registry.js +24 -7
- package/dist/server/rpc/handle-request.js +48 -3
- package/dist/server/rpc/handlers/completion-stream-delegated.js +2 -1
- package/dist/server/rpc/handlers/completion-stream.js +11 -4
- package/dist/server/rpc/handlers/download-asset.js +2 -3
- package/dist/server/rpc/handlers/get-model-info.d.ts +3 -0
- package/dist/server/rpc/handlers/get-model-info.js +148 -0
- package/dist/server/rpc/handlers/index.d.ts +6 -0
- package/dist/server/rpc/handlers/index.js +8 -0
- package/dist/server/rpc/handlers/load-model/download-manager.d.ts +1 -0
- package/dist/server/rpc/handlers/load-model/download-manager.js +12 -31
- package/dist/server/rpc/handlers/load-model/http.js +51 -10
- package/dist/server/rpc/handlers/load-model/hyperdrive.js +336 -156
- package/dist/server/rpc/handlers/load-model/index.js +1 -1
- package/dist/server/rpc/handlers/load-model/resolve.d.ts +1 -1
- package/dist/server/rpc/handlers/load-model/resolve.js +17 -60
- package/dist/server/rpc/handlers/load-model-delegated.js +7 -4
- package/dist/server/rpc/handlers/load-model.js +19 -1
- package/dist/server/rpc/handlers/provideHandler/handler.js +2 -1
- package/dist/server/rpc/handlers/rag.js +0 -3
- package/dist/server/rpc/handlers/set-config.d.ts +3 -0
- package/dist/server/rpc/handlers/set-config.js +18 -0
- package/dist/server/rpc/handlers/stopProvideHandler.d.ts +3 -0
- package/dist/server/rpc/handlers/stopProvideHandler.js +22 -0
- package/dist/server/rpc/handlers/text-to-speech.d.ts +3 -0
- package/dist/server/rpc/handlers/text-to-speech.js +7 -0
- package/dist/server/rpc/handlers/transcribe-stream.js +6 -2
- package/dist/server/rpc/handlers/unload-model.js +7 -0
- package/dist/server/utils/cache.d.ts +13 -8
- package/dist/server/utils/cache.js +69 -14
- package/dist/server/utils/checksum.d.ts +2 -0
- package/dist/server/utils/checksum.js +24 -0
- package/dist/server/utils/index.d.ts +2 -0
- package/dist/server/utils/index.js +2 -0
- package/dist/server/utils/shard-utils.d.ts +22 -0
- package/dist/server/utils/shard-utils.js +37 -0
- package/dist/server/utils/tool-integration.d.ts +13 -0
- package/dist/server/utils/tool-integration.js +43 -0
- package/dist/server/utils/tool-parser.d.ts +7 -0
- package/dist/server/utils/tool-parser.js +244 -0
- package/dist/server/worker.js +28 -10
- package/dist/utils/errors-base.d.ts +3 -0
- package/dist/utils/errors-base.js +13 -0
- package/dist/utils/errors-client.d.ts +107 -0
- package/dist/utils/errors-client.js +186 -0
- package/dist/utils/errors-server.d.ts +146 -0
- package/dist/utils/errors-server.js +253 -0
- package/dist/utils/tool-helpers.d.ts +17 -0
- package/dist/utils/tool-helpers.js +99 -0
- package/package.json +15 -11
- package/dist/examples/llamacpp-tools-routing.d.ts +0 -2
- package/dist/examples/llamacpp-tools-routing.js +0 -364
- package/dist/examples/llamacpp-tools.d.ts +0 -2
- package/dist/examples/llamacpp-tools.js +0 -81
- package/dist/server/http-server.d.ts +0 -2
- package/dist/server/http-server.js +0 -189
|
@@ -1,55 +1,86 @@
|
|
|
1
|
-
import { promises as fsPromises } from "bare-fs";
|
|
2
|
-
import path from "bare-path";
|
|
3
|
-
import process from "bare-process";
|
|
4
|
-
import { registerModel, isModelLoaded, } from "../registry/model-registry.js";
|
|
5
1
|
import { loadModelServerParamsSchema, } from "../../../schemas/index.js";
|
|
6
|
-
import {
|
|
7
|
-
import { createLlmModel } from "./llamacpp/index.js";
|
|
8
|
-
import { createEmbeddingsModel } from "./llamacpp/index.js";
|
|
2
|
+
import { createEmbeddingsModel, createLlmModel, } from "./llamacpp/index.js";
|
|
9
3
|
import { createNmtModel } from "./translation/index.js";
|
|
4
|
+
import { createTtsModel } from "./tts/index.js";
|
|
5
|
+
import { createWhisperModel } from "./whispercpp/index.js";
|
|
6
|
+
import { isModelLoaded, registerModel, } from "../registry/model-registry.js";
|
|
7
|
+
import { detectShardedModel, generateShardFilenames } from "../../utils/index.js";
|
|
8
|
+
import { ESpeakDataPathRequiredError, UnknownModelTypeError, ModelFileNotFoundError, ModelFileNotFoundInDirError, ModelFileLocateFailedError, } from "../../../utils/errors-server.js";
|
|
9
|
+
import { promises as fsPromises } from "bare-fs";
|
|
10
|
+
import path from "bare-path";
|
|
10
11
|
export async function loadModel(params) {
|
|
11
|
-
const { modelId, modelPath, options, projectionModelPath, vadModelPath } = loadModelServerParamsSchema.parse(params);
|
|
12
|
+
const { modelId, modelPath, options, projectionModelPath, vadModelPath, ttsConfigModelPath, eSpeakDataPath, modelName, } = loadModelServerParamsSchema.parse(params);
|
|
12
13
|
const { modelConfig, modelType } = options;
|
|
13
14
|
// Check if model is already loaded
|
|
14
15
|
if (isModelLoaded(modelId)) {
|
|
15
16
|
console.log(`${modelType} model ${modelId} is already loaded`);
|
|
16
17
|
return;
|
|
17
18
|
}
|
|
18
|
-
//
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
// Detect if sharded model
|
|
20
|
+
const modelFileName = path.basename(modelPath);
|
|
21
|
+
const shardInfo = detectShardedModel(modelFileName);
|
|
22
|
+
const isShardedModel = shardInfo.isSharded;
|
|
23
|
+
if (isShardedModel) {
|
|
24
|
+
// For sharded models, validate all required files exist
|
|
25
|
+
const shardDir = path.dirname(modelPath);
|
|
26
|
+
const allRequiredFiles = generateShardFilenames(modelFileName);
|
|
27
|
+
for (const shardFile of allRequiredFiles) {
|
|
28
|
+
const shardPath = path.join(shardDir, shardFile);
|
|
29
|
+
try {
|
|
30
|
+
await fsPromises.access(shardPath);
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
throw new ModelFileNotFoundError(`${shardFile}. Expected ${allRequiredFiles.length} files (shards + companion files) in ${shardDir}`, error);
|
|
34
|
+
}
|
|
26
35
|
}
|
|
27
|
-
// File exists, continue
|
|
28
36
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
37
|
+
else {
|
|
38
|
+
// For non-sharded models, validate single file exists
|
|
39
|
+
try {
|
|
40
|
+
const modelDir = path.dirname(modelPath);
|
|
41
|
+
const modelFile = path.basename(modelPath);
|
|
42
|
+
const files = (await fsPromises.readdir(modelDir));
|
|
43
|
+
if (!files.includes(modelFile)) {
|
|
44
|
+
throw new ModelFileNotFoundInDirError(modelFile, modelDir, modelType);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
console.error(`Error reading ${modelType} model directory:`, error instanceof Error ? error.message : String(error));
|
|
49
|
+
throw new ModelFileLocateFailedError(modelType, modelPath, error);
|
|
50
|
+
}
|
|
32
51
|
}
|
|
33
|
-
let
|
|
52
|
+
let result;
|
|
34
53
|
switch (modelType) {
|
|
35
54
|
case "llm":
|
|
36
|
-
|
|
55
|
+
result = createLlmModel(modelId, modelPath, modelConfig, projectionModelPath);
|
|
37
56
|
break;
|
|
38
57
|
case "whisper":
|
|
39
|
-
|
|
58
|
+
result = createWhisperModel(modelId, modelPath, modelConfig, vadModelPath);
|
|
40
59
|
break;
|
|
41
60
|
case "embeddings":
|
|
42
|
-
|
|
61
|
+
result = createEmbeddingsModel(modelId, modelPath, modelConfig);
|
|
43
62
|
break;
|
|
44
63
|
case "nmt":
|
|
45
|
-
|
|
64
|
+
result = createNmtModel(modelId, modelPath, modelConfig);
|
|
65
|
+
break;
|
|
66
|
+
case "tts":
|
|
67
|
+
if (!eSpeakDataPath) {
|
|
68
|
+
throw new ESpeakDataPathRequiredError();
|
|
69
|
+
}
|
|
70
|
+
result = createTtsModel(modelId, modelPath, modelConfig, ttsConfigModelPath, eSpeakDataPath);
|
|
46
71
|
break;
|
|
47
72
|
default:
|
|
48
73
|
// Should never happen
|
|
49
|
-
throw new
|
|
74
|
+
throw new UnknownModelTypeError(modelType);
|
|
50
75
|
}
|
|
51
76
|
console.log(`${modelType}: Loading model ${modelId}...`);
|
|
52
|
-
await model.load(false);
|
|
77
|
+
await result.model.load(false);
|
|
53
78
|
console.log(`${modelType} model ${modelId} loaded`);
|
|
54
|
-
registerModel(modelId, {
|
|
79
|
+
registerModel(modelId, {
|
|
80
|
+
model: result.model,
|
|
81
|
+
path: modelPath,
|
|
82
|
+
config: modelConfig,
|
|
83
|
+
name: modelName,
|
|
84
|
+
loader: result.loader,
|
|
85
|
+
});
|
|
55
86
|
}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import { type AnyModel } from "../../registry/model-registry";
|
|
2
2
|
import { type NmtConfig } from "../../../../schemas/index";
|
|
3
|
-
|
|
3
|
+
import FilesystemDL from "@qvac/dl-filesystem";
|
|
4
|
+
export declare function createNmtModel(modelId: string, modelPath: string, nmtConfig: NmtConfig): {
|
|
5
|
+
model: AnyModel;
|
|
6
|
+
loader: FilesystemDL;
|
|
7
|
+
};
|
|
4
8
|
//# sourceMappingURL=create-model.d.ts.map
|
|
@@ -1,45 +1,37 @@
|
|
|
1
1
|
import TranslationNmtcpp from "@qvac/translation-nmtcpp";
|
|
2
|
-
import { Readable } from "bare-stream";
|
|
3
2
|
import {} from "../../registry/model-registry.js";
|
|
4
3
|
import { INDICTRANS_LANGUAGES } from "../../../../schemas/index.js";
|
|
5
4
|
import { createStreamLogger } from "../../../../logging/index.js";
|
|
6
5
|
import { parseModelPath } from "../../../utils/index.js";
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
return {
|
|
10
|
-
dirPath: options.dirPath,
|
|
11
|
-
getStream: () => {
|
|
12
|
-
return Promise.resolve(Readable.from([]));
|
|
13
|
-
},
|
|
14
|
-
ready: () => Promise.resolve(),
|
|
15
|
-
close: () => Promise.resolve(),
|
|
16
|
-
destroy: () => Promise.resolve(),
|
|
17
|
-
start: () => Promise.resolve(),
|
|
18
|
-
stop: () => Promise.resolve(),
|
|
19
|
-
};
|
|
20
|
-
}
|
|
6
|
+
import FilesystemDL from "@qvac/dl-filesystem";
|
|
7
|
+
import { TranslationFailedError } from "../../../../utils/errors-server.js";
|
|
21
8
|
export function createNmtModel(modelId, modelPath, nmtConfig) {
|
|
22
9
|
const { dirPath, basePath } = parseModelPath(modelPath);
|
|
23
|
-
const
|
|
24
|
-
dirPath: "./",
|
|
25
|
-
});
|
|
10
|
+
const loader = new FilesystemDL({ dirPath });
|
|
26
11
|
const logger = createStreamLogger(modelId, "nmtcpp");
|
|
12
|
+
const { mode, from, to, ...generationParams } = nmtConfig;
|
|
27
13
|
const args = {
|
|
28
|
-
loader
|
|
14
|
+
loader,
|
|
29
15
|
logger,
|
|
30
16
|
modelName: basePath,
|
|
31
17
|
diskPath: dirPath,
|
|
32
18
|
params: {
|
|
33
|
-
mode
|
|
34
|
-
srcLang:
|
|
35
|
-
dstLang:
|
|
19
|
+
mode,
|
|
20
|
+
srcLang: from,
|
|
21
|
+
dstLang: to,
|
|
36
22
|
},
|
|
37
23
|
};
|
|
38
24
|
const config = {
|
|
39
|
-
modelType: INDICTRANS_LANGUAGES.includes(
|
|
40
|
-
INDICTRANS_LANGUAGES.includes(
|
|
25
|
+
modelType: INDICTRANS_LANGUAGES.includes(from) &&
|
|
26
|
+
INDICTRANS_LANGUAGES.includes(to)
|
|
41
27
|
? TranslationNmtcpp.ModelTypes.IndicTrans
|
|
42
28
|
: TranslationNmtcpp.ModelTypes.Opus,
|
|
29
|
+
...generationParams,
|
|
43
30
|
};
|
|
44
|
-
|
|
31
|
+
// Fail fast if model type is IndicTrans
|
|
32
|
+
if (config.modelType === TranslationNmtcpp.ModelTypes.IndicTrans) {
|
|
33
|
+
throw new TranslationFailedError("IndicTrans models are not supported with current NMT addon version.");
|
|
34
|
+
}
|
|
35
|
+
const model = new TranslationNmtcpp(args, config);
|
|
36
|
+
return { model, loader };
|
|
45
37
|
}
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { getModel } from "../../../registry/model-registry.js";
|
|
2
2
|
import { translateServerParamsSchema, } from "../../../../../schemas/index.js";
|
|
3
|
+
import { getLangName } from "@qvac/langdetect-text";
|
|
4
|
+
function getLanguage(code) {
|
|
5
|
+
if (!code)
|
|
6
|
+
return "";
|
|
7
|
+
const fullName = getLangName(code);
|
|
8
|
+
return fullName ?? code.toUpperCase();
|
|
9
|
+
}
|
|
3
10
|
export async function* translate(params) {
|
|
4
11
|
const { modelId, text, modelType } = params;
|
|
5
12
|
const from = params.modelType === "llm" ? params.from : undefined;
|
|
@@ -7,13 +14,15 @@ export async function* translate(params) {
|
|
|
7
14
|
const context = params.modelType === "llm" ? params.context : undefined;
|
|
8
15
|
translateServerParamsSchema.parse(params);
|
|
9
16
|
const model = getModel(modelId);
|
|
17
|
+
const fromLanguage = getLanguage(from);
|
|
18
|
+
const toLanguage = getLanguage(to);
|
|
10
19
|
// Prepare input based on model type
|
|
11
20
|
const input = modelType === "nmt"
|
|
12
21
|
? text
|
|
13
22
|
: [
|
|
14
23
|
{
|
|
15
24
|
role: "system",
|
|
16
|
-
content: `${context ? `${context}. ` : ""}Translate the following text from ${
|
|
25
|
+
content: `${context ? `${context}. ` : ""}Translate the following text from ${fromLanguage} into ${toLanguage}. Only output the translation, nothing else.\n\n${fromLanguage}: ${text}\n${toLanguage}:`,
|
|
17
26
|
},
|
|
18
27
|
];
|
|
19
28
|
const startTime = Date.now();
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import ONNXTTS from "@qvac/tts-onnx";
|
|
2
|
+
import { type AnyModel } from "../../registry/model-registry";
|
|
3
|
+
import { type TtsConfig } from "../../../../schemas/index";
|
|
4
|
+
import FilesystemDL from "@qvac/dl-filesystem";
|
|
5
|
+
export type TtsModel = ONNXTTS;
|
|
6
|
+
export declare function createTtsModel(modelId: string, modelPath: string, ttsConfig: TtsConfig, ttsConfigModelPath: string, eSpeakDataPath: string): {
|
|
7
|
+
model: AnyModel;
|
|
8
|
+
loader: FilesystemDL;
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=create-model.d.ts.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import ONNXTTS from "@qvac/tts-onnx";
|
|
2
|
+
import {} from "../../registry/model-registry.js";
|
|
3
|
+
import {} from "../../../../schemas/index.js";
|
|
4
|
+
import { createStreamLogger } from "../../../../logging/index.js";
|
|
5
|
+
import { parseModelPath } from "../../../utils/index.js";
|
|
6
|
+
import FilesystemDL from "@qvac/dl-filesystem";
|
|
7
|
+
export function createTtsModel(modelId, modelPath, ttsConfig, ttsConfigModelPath, eSpeakDataPath) {
|
|
8
|
+
const { dirPath, basePath: fileName } = parseModelPath(modelPath);
|
|
9
|
+
const loader = new FilesystemDL({ dirPath });
|
|
10
|
+
const logger = createStreamLogger(modelId, "tts");
|
|
11
|
+
const args = {
|
|
12
|
+
loader,
|
|
13
|
+
logger,
|
|
14
|
+
mainModelUrl: fileName,
|
|
15
|
+
configJsonPath: parseModelPath(ttsConfigModelPath).basePath,
|
|
16
|
+
cache: dirPath,
|
|
17
|
+
eSpeakDataPath: eSpeakDataPath,
|
|
18
|
+
opts: { stats: true },
|
|
19
|
+
};
|
|
20
|
+
const config = {
|
|
21
|
+
language: ttsConfig.language,
|
|
22
|
+
};
|
|
23
|
+
const model = new ONNXTTS(args, config);
|
|
24
|
+
return { model, loader };
|
|
25
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { getModel } from "../../../registry/model-registry.js";
|
|
2
|
+
import { ttsRequestSchema } from "../../../../../schemas/index.js";
|
|
3
|
+
export async function* textToSpeech(params) {
|
|
4
|
+
const { modelId, inputType, text, stream } = ttsRequestSchema.parse(params);
|
|
5
|
+
const model = getModel(modelId);
|
|
6
|
+
const response = await model.run({ input: text, inputType });
|
|
7
|
+
if (!stream) {
|
|
8
|
+
// Non-streaming mode: wait for complete response and yield once
|
|
9
|
+
let completeBuffer = [];
|
|
10
|
+
await response
|
|
11
|
+
.onUpdate((data) => {
|
|
12
|
+
completeBuffer = completeBuffer.concat(Array.from(data.outputArray));
|
|
13
|
+
})
|
|
14
|
+
.await();
|
|
15
|
+
yield {
|
|
16
|
+
type: "textToSpeech",
|
|
17
|
+
buffer: completeBuffer,
|
|
18
|
+
done: true,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
// Streaming mode: use async iterator pattern
|
|
23
|
+
const outputQueue = [];
|
|
24
|
+
let isComplete = false;
|
|
25
|
+
let resolveNext = null;
|
|
26
|
+
// Start the response processing
|
|
27
|
+
const responsePromise = response
|
|
28
|
+
.onUpdate((data) => {
|
|
29
|
+
if (resolveNext) {
|
|
30
|
+
// If there's a pending read, resolve it immediately
|
|
31
|
+
resolveNext({
|
|
32
|
+
value: {
|
|
33
|
+
type: "textToSpeech",
|
|
34
|
+
buffer: Array.from(data.outputArray),
|
|
35
|
+
done: false,
|
|
36
|
+
},
|
|
37
|
+
done: false,
|
|
38
|
+
});
|
|
39
|
+
resolveNext = null;
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
// Otherwise, queue the output
|
|
43
|
+
outputQueue.push(data);
|
|
44
|
+
}
|
|
45
|
+
})
|
|
46
|
+
.await()
|
|
47
|
+
.then(() => {
|
|
48
|
+
isComplete = true;
|
|
49
|
+
if (resolveNext) {
|
|
50
|
+
resolveNext({ value: undefined, done: true });
|
|
51
|
+
resolveNext = null;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
// Create an async iterator
|
|
55
|
+
const asyncIterator = {
|
|
56
|
+
async next() {
|
|
57
|
+
if (outputQueue.length > 0) {
|
|
58
|
+
const data = outputQueue.shift();
|
|
59
|
+
return {
|
|
60
|
+
value: {
|
|
61
|
+
type: "textToSpeech",
|
|
62
|
+
buffer: Array.from(data.outputArray),
|
|
63
|
+
done: false,
|
|
64
|
+
},
|
|
65
|
+
done: false,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
if (isComplete) {
|
|
69
|
+
return { value: undefined, done: true };
|
|
70
|
+
}
|
|
71
|
+
// Wait for the next output
|
|
72
|
+
return new Promise((resolve) => {
|
|
73
|
+
resolveNext = resolve;
|
|
74
|
+
});
|
|
75
|
+
},
|
|
76
|
+
[Symbol.asyncIterator]() {
|
|
77
|
+
return this;
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
// Yield outputs as they come
|
|
81
|
+
for await (const output of asyncIterator) {
|
|
82
|
+
yield output;
|
|
83
|
+
}
|
|
84
|
+
// Ensure the response is fully processed
|
|
85
|
+
await responsePromise;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -1,19 +1,37 @@
|
|
|
1
1
|
import { promises as fsPromises } from "bare-fs";
|
|
2
|
+
import path from "bare-path";
|
|
2
3
|
import { unregisterModel } from "../registry/model-registry.js";
|
|
3
4
|
import { unregisterAllLoggingStreams } from "../registry/logging-stream-registry.js";
|
|
4
5
|
import { unloadModelParamsSchema } from "../../../schemas/index.js";
|
|
6
|
+
import { ModelNotLoadedError } from "../../../utils/errors-server.js";
|
|
7
|
+
import { detectShardedModel } from "../../utils/index.js";
|
|
5
8
|
export async function unloadModel(params) {
|
|
6
9
|
const { modelId, clearStorage } = unloadModelParamsSchema.parse(params);
|
|
7
10
|
const entry = unregisterModel(modelId);
|
|
8
11
|
if (!entry) {
|
|
9
|
-
throw new
|
|
12
|
+
throw new ModelNotLoadedError(modelId);
|
|
13
|
+
}
|
|
14
|
+
if (entry.local?.loader) {
|
|
15
|
+
await entry.local.loader.close();
|
|
10
16
|
}
|
|
11
17
|
if (entry.local?.model && entry.local.model.unload) {
|
|
12
18
|
await entry.local.model.unload();
|
|
13
19
|
}
|
|
14
20
|
if (clearStorage && entry.local?.path) {
|
|
15
|
-
|
|
16
|
-
|
|
21
|
+
const modelPath = entry.local.path;
|
|
22
|
+
const modelFileName = path.basename(modelPath);
|
|
23
|
+
const shardInfo = detectShardedModel(modelFileName);
|
|
24
|
+
if (shardInfo.isSharded) {
|
|
25
|
+
// Delete entire shard directory
|
|
26
|
+
const shardDir = path.dirname(modelPath);
|
|
27
|
+
await fsPromises.rm(shardDir, { recursive: true, force: true });
|
|
28
|
+
console.log(`Sharded model storage cleared: ${shardDir}`);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
// Delete single file
|
|
32
|
+
await fsPromises.rm(modelPath, { recursive: true, force: true });
|
|
33
|
+
console.log(`Model storage cleared: ${modelPath}`);
|
|
34
|
+
}
|
|
17
35
|
}
|
|
18
36
|
unregisterAllLoggingStreams(modelId);
|
|
19
37
|
console.log(`Model ${modelId} unloaded`);
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import TranscriptionWhispercpp from "@qvac/transcription-whispercpp";
|
|
2
2
|
import { type AnyModel } from "../../registry/model-registry";
|
|
3
3
|
import { type WhisperConfig } from "../../../../schemas/index";
|
|
4
|
+
import FilesystemDL from "@qvac/dl-filesystem";
|
|
4
5
|
export type WhispercppModel = TranscriptionWhispercpp;
|
|
5
|
-
export declare function createWhisperModel(modelId: string, modelPath: string, whisperConfig: WhisperConfig, vadModelPath?: string):
|
|
6
|
+
export declare function createWhisperModel(modelId: string, modelPath: string, whisperConfig: WhisperConfig, vadModelPath?: string): {
|
|
7
|
+
model: AnyModel;
|
|
8
|
+
loader: FilesystemDL;
|
|
9
|
+
};
|
|
6
10
|
//# sourceMappingURL=create-model.d.ts.map
|
|
@@ -1,42 +1,22 @@
|
|
|
1
1
|
import TranscriptionWhispercpp from "@qvac/transcription-whispercpp";
|
|
2
|
-
import { Readable } from "bare-stream";
|
|
3
2
|
import {} from "../../registry/model-registry.js";
|
|
4
3
|
import {} from "../../../../schemas/index.js";
|
|
5
4
|
import { createStreamLogger } from "../../../../logging/index.js";
|
|
6
5
|
import { parseModelPath } from "../../../utils/index.js";
|
|
7
|
-
|
|
8
|
-
function createFilesystemDLMimic(options) {
|
|
9
|
-
return {
|
|
10
|
-
dirPath: options.dirPath,
|
|
11
|
-
getStream: () => {
|
|
12
|
-
return Readable.from([]);
|
|
13
|
-
},
|
|
14
|
-
ready: () => Promise.resolve(),
|
|
15
|
-
close: () => Promise.resolve(),
|
|
16
|
-
destroy: () => Promise.resolve(),
|
|
17
|
-
getFileSize: () => Promise.resolve(0),
|
|
18
|
-
download: () => Promise.resolve({
|
|
19
|
-
await: () => Promise.resolve(),
|
|
20
|
-
}),
|
|
21
|
-
downloadFiles: () => Promise.resolve([]),
|
|
22
|
-
};
|
|
23
|
-
}
|
|
6
|
+
import FilesystemDL from "@qvac/dl-filesystem";
|
|
24
7
|
export function createWhisperModel(modelId, modelPath, whisperConfig, vadModelPath) {
|
|
25
8
|
const { dirPath, basePath } = parseModelPath(modelPath);
|
|
26
|
-
// Handle VAD model path
|
|
9
|
+
// Handle VAD model path
|
|
27
10
|
let vadModelName = "";
|
|
28
|
-
|
|
29
|
-
if (
|
|
30
|
-
const vadParsed = parseModelPath(
|
|
31
|
-
vadDirPath = vadParsed.dirPath;
|
|
11
|
+
const effectiveVadPath = vadModelPath || whisperConfig.vad_model_path;
|
|
12
|
+
if (effectiveVadPath) {
|
|
13
|
+
const vadParsed = parseModelPath(effectiveVadPath);
|
|
32
14
|
vadModelName = vadParsed.basePath;
|
|
33
15
|
}
|
|
34
|
-
const
|
|
35
|
-
dirPath: vadDirPath,
|
|
36
|
-
});
|
|
16
|
+
const loader = new FilesystemDL({ dirPath });
|
|
37
17
|
const logger = createStreamLogger(modelId, "whispercpp");
|
|
38
18
|
const args = {
|
|
39
|
-
loader
|
|
19
|
+
loader,
|
|
40
20
|
logger,
|
|
41
21
|
modelName: basePath,
|
|
42
22
|
diskPath: dirPath,
|
|
@@ -45,11 +25,12 @@ export function createWhisperModel(modelId, modelPath, whisperConfig, vadModelPa
|
|
|
45
25
|
stats: false,
|
|
46
26
|
},
|
|
47
27
|
};
|
|
28
|
+
const { contextParams, miscConfig, ...whisperParams } = whisperConfig;
|
|
48
29
|
const config = {
|
|
49
|
-
whisperConfig:
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
},
|
|
30
|
+
whisperConfig: whisperParams,
|
|
31
|
+
...(contextParams && { contextParams }),
|
|
32
|
+
...(miscConfig && { miscConfig }),
|
|
53
33
|
};
|
|
54
|
-
|
|
34
|
+
const model = new TranscriptionWhispercpp(args, config);
|
|
35
|
+
return { model, loader };
|
|
55
36
|
}
|
|
@@ -1,30 +1,51 @@
|
|
|
1
|
-
import { getModel } from "../../../registry/model-registry.js";
|
|
1
|
+
import { getModel, getModelConfig, updateModelConfig, } from "../../../registry/model-registry.js";
|
|
2
2
|
import { Readable } from "bare-stream";
|
|
3
3
|
import fs from "bare-fs";
|
|
4
4
|
import { needsDecoding, decodeAudioToStream } from "../../../../utils/index.js";
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
5
|
+
import {} from "../../../../../schemas/index.js";
|
|
6
|
+
import { AudioFileNotFoundError, InvalidAudioChunkError, } from "../../../../../utils/errors-server.js";
|
|
7
7
|
export async function* transcribe(params) {
|
|
8
|
-
const
|
|
9
|
-
|
|
8
|
+
const model = getModel(params.modelId);
|
|
9
|
+
if (params.prompt && typeof model.reload === "function") {
|
|
10
|
+
const existingConfig = getModelConfig(params.modelId);
|
|
11
|
+
const updatedConfig = {
|
|
12
|
+
...existingConfig,
|
|
13
|
+
initial_prompt: params.prompt,
|
|
14
|
+
};
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
16
|
+
const { contextParams: _, miscConfig, ...whisperParams } = updatedConfig;
|
|
17
|
+
await model.reload({
|
|
18
|
+
whisperConfig: whisperParams,
|
|
19
|
+
...(miscConfig && { miscConfig }),
|
|
20
|
+
});
|
|
21
|
+
updateModelConfig(params.modelId, updatedConfig);
|
|
22
|
+
}
|
|
10
23
|
let audioStream;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
audioStream = await decodeAudioToStream(audioInput);
|
|
24
|
+
const audioChunk = params.audioChunk;
|
|
25
|
+
switch (audioChunk.type) {
|
|
26
|
+
case "base64": {
|
|
27
|
+
const audioBuffer = Buffer.from(audioChunk.value, "base64");
|
|
28
|
+
audioStream = Readable.from([audioBuffer]);
|
|
29
|
+
break;
|
|
18
30
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
31
|
+
case "filePath": {
|
|
32
|
+
const filePath = audioChunk.value;
|
|
33
|
+
try {
|
|
34
|
+
fs.accessSync(filePath);
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
throw new AudioFileNotFoundError(filePath, error);
|
|
38
|
+
}
|
|
39
|
+
if (needsDecoding(filePath)) {
|
|
40
|
+
audioStream = await decodeAudioToStream(filePath);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
audioStream = fs.createReadStream(filePath);
|
|
44
|
+
}
|
|
45
|
+
break;
|
|
22
46
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
// It's base64 encoded buffer - decode and create stream
|
|
26
|
-
const audioBuffer = Buffer.from(audioInput, "base64");
|
|
27
|
-
audioStream = Readable.from([audioBuffer]);
|
|
47
|
+
default:
|
|
48
|
+
throw new InvalidAudioChunkError();
|
|
28
49
|
}
|
|
29
50
|
// Run transcription with streaming enabled
|
|
30
51
|
const response = await model.run(audioStream);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { getSwarm } from "./hyperswarm.js";
|
|
2
2
|
import RPC from "bare-rpc";
|
|
3
3
|
import { withTimeout } from "../../utils/withTimeout.js";
|
|
4
|
+
import { DelegateConnectionFailedError } from "../../utils/errors-server.js";
|
|
4
5
|
// Map of active RPC instances by public key
|
|
5
6
|
const activeRPCs = new Map();
|
|
6
7
|
// Establish RPC connection to a peer if not already connected
|
|
@@ -27,7 +28,7 @@ async function ensureRPCConnection(topic, publicKey, timeout) {
|
|
|
27
28
|
if (!rpc) {
|
|
28
29
|
console.error(`❌ No RPC instance found for peer ${publicKey}`);
|
|
29
30
|
console.log(`📊 Available RPC connections:`, Array.from(activeRPCs.keys()));
|
|
30
|
-
throw new
|
|
31
|
+
throw new DelegateConnectionFailedError(`Could not establish RPC connection to peer ${publicKey} on topic ${topic}`);
|
|
31
32
|
}
|
|
32
33
|
else {
|
|
33
34
|
console.log(`✅ RPC instance found for peer ${publicKey}`);
|
|
@@ -37,7 +38,7 @@ async function ensureRPCConnection(topic, publicKey, timeout) {
|
|
|
37
38
|
}
|
|
38
39
|
catch (error) {
|
|
39
40
|
console.error("Failed to establish RPC connection:", error);
|
|
40
|
-
throw new
|
|
41
|
+
throw new DelegateConnectionFailedError(`RPC connection failed: ${error instanceof Error ? error.message : String(error)}`, error);
|
|
41
42
|
}
|
|
42
43
|
}
|
|
43
44
|
return rpc;
|
|
@@ -3,5 +3,8 @@ import { type FirewallConfig } from "../../schemas/provide";
|
|
|
3
3
|
export declare function getSwarm({ firewallConfig, }?: {
|
|
4
4
|
firewallConfig?: FirewallConfig | undefined;
|
|
5
5
|
}): Hyperswarm;
|
|
6
|
+
export declare function registerProviderTopic(topic: string): void;
|
|
7
|
+
export declare function unregisterProviderTopic(topic: string): void;
|
|
8
|
+
export declare function hasActiveProviders(): boolean;
|
|
6
9
|
export declare function destroySwarm(): Promise<void>;
|
|
7
10
|
//# sourceMappingURL=hyperswarm.d.ts.map
|
|
@@ -2,6 +2,7 @@ import process from "bare-process";
|
|
|
2
2
|
import Hyperswarm from "hyperswarm";
|
|
3
3
|
import crypto from "bare-crypto";
|
|
4
4
|
import { envSchema } from "../../schemas/provide.js";
|
|
5
|
+
import { getSDKConfig } from "./registry/config-registry.js";
|
|
5
6
|
function getHyperswarmSeedBuffer() {
|
|
6
7
|
const parsedEnv = envSchema.safeParse(process.env);
|
|
7
8
|
if (parsedEnv.success) {
|
|
@@ -45,9 +46,19 @@ function createFirewallFunction(config) {
|
|
|
45
46
|
function createSwarm(firewallConfig) {
|
|
46
47
|
const seed = getHyperswarmSeedBuffer();
|
|
47
48
|
const firewall = createFirewallFunction(firewallConfig);
|
|
48
|
-
|
|
49
|
+
const getRelays = () => {
|
|
50
|
+
const config = getSDKConfig();
|
|
51
|
+
const relayPublicKeys = config.swarmRelays;
|
|
52
|
+
if (!relayPublicKeys || relayPublicKeys.length === 0) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
return relayPublicKeys.map((key) => Buffer.from(key, "hex"));
|
|
56
|
+
};
|
|
57
|
+
const swarmOptions = { seed, firewall, relayThrough: getRelays };
|
|
58
|
+
return new Hyperswarm(swarmOptions);
|
|
49
59
|
}
|
|
50
60
|
let swarm;
|
|
61
|
+
const activeProviderTopics = new Set();
|
|
51
62
|
export function getSwarm({ firewallConfig, } = {}) {
|
|
52
63
|
if (swarm) {
|
|
53
64
|
return swarm;
|
|
@@ -55,8 +66,18 @@ export function getSwarm({ firewallConfig, } = {}) {
|
|
|
55
66
|
swarm = createSwarm(firewallConfig);
|
|
56
67
|
return swarm;
|
|
57
68
|
}
|
|
69
|
+
export function registerProviderTopic(topic) {
|
|
70
|
+
activeProviderTopics.add(topic);
|
|
71
|
+
}
|
|
72
|
+
export function unregisterProviderTopic(topic) {
|
|
73
|
+
activeProviderTopics.delete(topic);
|
|
74
|
+
}
|
|
75
|
+
export function hasActiveProviders() {
|
|
76
|
+
return activeProviderTopics.size > 0;
|
|
77
|
+
}
|
|
58
78
|
export async function destroySwarm() {
|
|
59
79
|
if (swarm) {
|
|
80
|
+
activeProviderTopics.clear();
|
|
60
81
|
return swarm.destroy();
|
|
61
82
|
}
|
|
62
83
|
}
|