@qvac/sdk 0.3.0 → 0.4.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/README.md +22 -0
- 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 +3 -0
- package/dist/client/api/index.js +3 -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 +1 -1
- package/dist/client/api/stop-provider.js +4 -3
- 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 +69 -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 +20 -1
- package/dist/constants/audio.d.ts +1 -2
- package/dist/constants/audio.js +1 -17
- 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 +1916 -100
- package/dist/models/hyperdrive/models.js +2042 -102
- package/dist/schemas/common.d.ts +413 -58
- package/dist/schemas/common.js +9 -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 +7 -0
- package/dist/schemas/index.js +7 -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/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 +2 -3
- 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/model-registry.d.ts +13 -0
- package/dist/server/bare/registry/model-registry.js +24 -7
- package/dist/server/rpc/handle-request.js +42 -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 +4 -0
- package/dist/server/rpc/handlers/index.js +6 -0
- 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 +10 -6
- 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.js +3 -1
- 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/audio/decoder.js +1 -1
- 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/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 +14 -10
- 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,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
|
}
|
|
@@ -2,6 +2,7 @@ import { RAG, HyperDBAdapter } from "@qvac/rag";
|
|
|
2
2
|
import Corestore from "corestore";
|
|
3
3
|
import path from "bare-path";
|
|
4
4
|
import { getEnv } from "../../worker.js";
|
|
5
|
+
import { RAGWorkspaceModelMismatchError } from "../../../utils/errors-server.js";
|
|
5
6
|
const ragInstances = new Map();
|
|
6
7
|
const defaultWorkspace = "default";
|
|
7
8
|
const getStorePath = (workspace) => {
|
|
@@ -14,9 +15,7 @@ export const getRagInstance = async (modelId, embeddingFunction, workspace) => {
|
|
|
14
15
|
if (existingEntry) {
|
|
15
16
|
// Validate model consistency
|
|
16
17
|
if (existingEntry.modelId !== modelId) {
|
|
17
|
-
throw new
|
|
18
|
-
`but you're trying to use model "${modelId}". ` +
|
|
19
|
-
`Use a different workspace or the same model.`);
|
|
18
|
+
throw new RAGWorkspaceModelMismatchError(key, existingEntry.modelId, modelId);
|
|
20
19
|
}
|
|
21
20
|
return existingEntry.rag;
|
|
22
21
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { SDKConfig } from "../../../schemas/index";
|
|
2
|
+
export declare const setSDKConfig: (config: SDKConfig) => void;
|
|
3
|
+
export declare const getSDKConfig: () => SDKConfig;
|
|
4
|
+
export declare const getConfiguredCacheDir: () => string;
|
|
5
|
+
//# sourceMappingURL=config-registry.d.ts.map
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import fs from "bare-fs";
|
|
2
|
+
import path from "bare-path";
|
|
3
|
+
import { getEnv } from "../../worker.js";
|
|
4
|
+
import { CacheDirNotAbsoluteError, CacheDirNotWritableError, } from "../../../utils/errors-server.js";
|
|
5
|
+
const configRegistry = {
|
|
6
|
+
cacheDirectory: undefined,
|
|
7
|
+
swarmRelays: undefined,
|
|
8
|
+
};
|
|
9
|
+
export const setSDKConfig = (config) => {
|
|
10
|
+
if (config.cacheDirectory !== undefined && config.cacheDirectory !== null) {
|
|
11
|
+
if (!path.isAbsolute(config.cacheDirectory)) {
|
|
12
|
+
throw new CacheDirNotAbsoluteError();
|
|
13
|
+
}
|
|
14
|
+
try {
|
|
15
|
+
fs.mkdirSync(config.cacheDirectory, { recursive: true });
|
|
16
|
+
const testFile = path.join(config.cacheDirectory, ".qvac-test");
|
|
17
|
+
fs.writeFileSync(testFile, "test");
|
|
18
|
+
fs.unlinkSync(testFile);
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
throw new CacheDirNotWritableError(config.cacheDirectory, error instanceof Error ? error.message : String(error), error);
|
|
22
|
+
}
|
|
23
|
+
configRegistry.cacheDirectory = config.cacheDirectory;
|
|
24
|
+
console.log(`✅ Cache directory set to: ${config.cacheDirectory}`);
|
|
25
|
+
}
|
|
26
|
+
if (config.swarmRelays !== undefined && config.swarmRelays !== null) {
|
|
27
|
+
configRegistry.swarmRelays = config.swarmRelays;
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
export const getSDKConfig = () => {
|
|
31
|
+
return { ...configRegistry };
|
|
32
|
+
};
|
|
33
|
+
const getDefaultCacheDir = () => {
|
|
34
|
+
const homeDir = getEnv().HOME_DIR;
|
|
35
|
+
return path.join(homeDir, ".qvac", "models");
|
|
36
|
+
};
|
|
37
|
+
export const getConfiguredCacheDir = () => {
|
|
38
|
+
return configRegistry.cacheDirectory || getDefaultCacheDir();
|
|
39
|
+
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type EventEmitter from "events";
|
|
2
|
+
import type FilesystemDL from "@qvac/dl-filesystem";
|
|
2
3
|
interface AddonInterface {
|
|
3
4
|
cancel(jobId?: string): Promise<void>;
|
|
4
5
|
}
|
|
@@ -8,6 +9,11 @@ export interface AnyModel {
|
|
|
8
9
|
onUpdate(callback: (data: string) => void): {
|
|
9
10
|
await: () => Promise<void>;
|
|
10
11
|
};
|
|
12
|
+
onUpdate(callback: (data: {
|
|
13
|
+
outputArray: Int16Array;
|
|
14
|
+
}) => void): {
|
|
15
|
+
await: () => Promise<void>;
|
|
16
|
+
};
|
|
11
17
|
onError(callback: (error: Error) => void): void;
|
|
12
18
|
onUpdate(callback: (data: Array<{
|
|
13
19
|
text: string;
|
|
@@ -20,6 +26,7 @@ export interface AnyModel {
|
|
|
20
26
|
}>>;
|
|
21
27
|
await(): Promise<void>;
|
|
22
28
|
}>;
|
|
29
|
+
reload?(config: unknown): Promise<void>;
|
|
23
30
|
unload?(): Promise<void>;
|
|
24
31
|
addon?: AddonInterface;
|
|
25
32
|
}
|
|
@@ -33,6 +40,8 @@ interface LocalOptions {
|
|
|
33
40
|
path: string;
|
|
34
41
|
loadedAt: Date;
|
|
35
42
|
config: unknown;
|
|
43
|
+
name?: string | undefined;
|
|
44
|
+
loader: FilesystemDL;
|
|
36
45
|
}
|
|
37
46
|
export interface ModelEntry {
|
|
38
47
|
id: string;
|
|
@@ -44,6 +53,8 @@ export declare function registerModel(id: string, options: {
|
|
|
44
53
|
model: AnyModel;
|
|
45
54
|
path: string;
|
|
46
55
|
config: unknown;
|
|
56
|
+
loader: FilesystemDL;
|
|
57
|
+
name?: string | undefined;
|
|
47
58
|
} | {
|
|
48
59
|
topic: string;
|
|
49
60
|
providerPublicKey: string;
|
|
@@ -59,8 +70,10 @@ export declare function getModelInfo(id: string): {
|
|
|
59
70
|
path: string;
|
|
60
71
|
loadedAt: Date;
|
|
61
72
|
config: unknown;
|
|
73
|
+
name?: string;
|
|
62
74
|
} | null;
|
|
63
75
|
export declare function getModelConfig(id: string): unknown;
|
|
76
|
+
export declare function updateModelConfig(id: string, config: unknown): void;
|
|
64
77
|
export declare function clearRegistry(): void;
|
|
65
78
|
export declare function getRegistryStats(): {
|
|
66
79
|
totalModels: number;
|