@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,46 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { models } from "../../../../models/hyperdrive/models.js";
|
|
2
2
|
import { hyperdriveUrlSchema } from "../../../../schemas/index.js";
|
|
3
3
|
import { getModelsCacheDir } from "../../../utils/index.js";
|
|
4
4
|
import { promises as fsPromises } from "bare-fs";
|
|
5
5
|
import path from "bare-path";
|
|
6
6
|
import { downloadModelFromHttp } from "./http.js";
|
|
7
7
|
import { downloadModelFromHyperdrive } from "./hyperdrive.js";
|
|
8
|
-
|
|
9
|
-
* Attempts to resolve a model from cache (without validation)
|
|
10
|
-
* Validation will be handled by the hyperdrive download logic
|
|
11
|
-
*/
|
|
12
|
-
async function tryResolveCachedModel(modelId) {
|
|
13
|
-
const cacheDir = getModelsCacheDir();
|
|
14
|
-
const cachedPath = path.join(cacheDir, modelId);
|
|
15
|
-
try {
|
|
16
|
-
await fsPromises.access(cachedPath);
|
|
17
|
-
// File exists - return null to let hyperdrive validation handle size/checksum
|
|
18
|
-
// This ensures partial downloads are properly resumed instead of being
|
|
19
|
-
// incorrectly validated and deleted
|
|
20
|
-
return null;
|
|
21
|
-
}
|
|
22
|
-
catch {
|
|
23
|
-
// File doesn't exist
|
|
24
|
-
return null;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Resolves a known model by ID from hyperdrive, checking cache first
|
|
29
|
-
*/
|
|
30
|
-
async function resolveKnownModel(model, modelIdOrPath, progressCallback, seed) {
|
|
31
|
-
if (!model) {
|
|
32
|
-
throw new Error("Model is null");
|
|
33
|
-
}
|
|
34
|
-
console.log(`Loading model ID '${modelIdOrPath}' from hyperdrive`);
|
|
35
|
-
// Try to resolve from cache first
|
|
36
|
-
const cachedPath = await tryResolveCachedModel(model.modelId);
|
|
37
|
-
if (cachedPath) {
|
|
38
|
-
return cachedPath;
|
|
39
|
-
}
|
|
40
|
-
// Not cached or invalid, download from hyperdrive
|
|
41
|
-
const downloadedPath = await downloadModelFromHyperdrive(model.hyperdriveKey, model.modelId, seed, progressCallback, model.sha256Checksum);
|
|
42
|
-
return downloadedPath;
|
|
43
|
-
}
|
|
8
|
+
import { ModelLoadFailedError, ModelNotFoundError, SeedingNotSupportedError, } from "../../../../utils/errors-server.js";
|
|
44
9
|
/**
|
|
45
10
|
* Resolves a local file path or cached file
|
|
46
11
|
*/
|
|
@@ -48,7 +13,7 @@ async function resolveLocalOrCachedFile(modelIdOrPath) {
|
|
|
48
13
|
// Check if it's a hex string (arbitrary hyperdrive key)
|
|
49
14
|
const isHexString = /^[0-9a-fA-F]{64}$/.test(modelIdOrPath);
|
|
50
15
|
if (isHexString) {
|
|
51
|
-
throw new
|
|
16
|
+
throw new ModelLoadFailedError(`Direct hyperdrive keys not supported. Use hyperdriveKey parameter instead. Example: loadModel("model.gguf", "${modelIdOrPath}")`);
|
|
52
17
|
}
|
|
53
18
|
// Check if it's a cached file or local file
|
|
54
19
|
const cacheDir = getModelsCacheDir();
|
|
@@ -68,26 +33,26 @@ async function resolveLocalOrCachedFile(modelIdOrPath) {
|
|
|
68
33
|
catch {
|
|
69
34
|
// Invalid model ID - provide helpful error
|
|
70
35
|
const availableModels = models.map((m) => m.modelId);
|
|
71
|
-
throw new
|
|
36
|
+
throw new ModelNotFoundError(`${modelIdOrPath}". Available models: ${availableModels.join(", ")}`);
|
|
72
37
|
}
|
|
73
38
|
}
|
|
74
39
|
}
|
|
40
|
+
import { modelInputToSrcSchema } from "../../../../schemas/index.js";
|
|
75
41
|
export async function resolveModelPath(modelSrc, progressCallback, seed) {
|
|
42
|
+
// Extract src and validate using Zod schema transform
|
|
43
|
+
const srcString = modelInputToSrcSchema.parse(modelSrc);
|
|
76
44
|
// Parse hyperdrive URLs if present
|
|
77
45
|
let hyperdriveKey;
|
|
78
|
-
let actualModelSrc =
|
|
79
|
-
if (
|
|
80
|
-
const { key, path } = hyperdriveUrlSchema.parse(
|
|
46
|
+
let actualModelSrc = srcString;
|
|
47
|
+
if (srcString.startsWith("pear://")) {
|
|
48
|
+
const { key, path } = hyperdriveUrlSchema.parse(srcString);
|
|
81
49
|
hyperdriveKey = key;
|
|
82
50
|
actualModelSrc = path;
|
|
83
51
|
}
|
|
84
52
|
let actualPath;
|
|
85
53
|
// Validate seeding is only used with hyperdrive models
|
|
86
54
|
if (seed && !hyperdriveKey) {
|
|
87
|
-
|
|
88
|
-
if (!model) {
|
|
89
|
-
throw new Error("Seeding is only supported for hyperdrive models");
|
|
90
|
-
}
|
|
55
|
+
throw new SeedingNotSupportedError();
|
|
91
56
|
}
|
|
92
57
|
// Check if it's an HTTP/HTTPS URL
|
|
93
58
|
if (actualModelSrc.startsWith("http://") ||
|
|
@@ -101,21 +66,13 @@ export async function resolveModelPath(modelSrc, progressCallback, seed) {
|
|
|
101
66
|
console.log(`Loading from hyperdrive: ${hyperdriveKey}`);
|
|
102
67
|
actualPath = await downloadModelFromHyperdrive(hyperdriveKey, actualModelSrc, seed, progressCallback);
|
|
103
68
|
}
|
|
69
|
+
else if (actualModelSrc.includes("/") || actualModelSrc.includes("\\")) {
|
|
70
|
+
// Handle file paths (absolute or relative with slashes)
|
|
71
|
+
actualPath = actualModelSrc;
|
|
72
|
+
}
|
|
104
73
|
else {
|
|
105
|
-
//
|
|
106
|
-
|
|
107
|
-
if (model) {
|
|
108
|
-
actualPath = await resolveKnownModel(model, actualModelSrc, progressCallback, seed);
|
|
109
|
-
}
|
|
110
|
-
else if (actualModelSrc.includes("/") || actualModelSrc.includes("\\")) {
|
|
111
|
-
// Handle file paths (absolute or relative with slashes)
|
|
112
|
-
console.log(`Loading from file: ${actualModelSrc}`);
|
|
113
|
-
actualPath = actualModelSrc;
|
|
114
|
-
}
|
|
115
|
-
else {
|
|
116
|
-
// Handle local files and cached files
|
|
117
|
-
actualPath = await resolveLocalOrCachedFile(actualModelSrc);
|
|
118
|
-
}
|
|
74
|
+
// Handle local files and cached files
|
|
75
|
+
actualPath = await resolveLocalOrCachedFile(actualModelSrc);
|
|
119
76
|
}
|
|
120
77
|
return actualPath;
|
|
121
78
|
}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import { modelInputToSrcSchema } from "../../../schemas/index.js";
|
|
1
2
|
import { registerModel } from "../../bare/registry/model-registry.js";
|
|
2
3
|
import { getRPC } from "../../bare/delegate-rpc-client.js";
|
|
3
4
|
import { send, stream } from "../../../client/rpc/rpc-client.js";
|
|
4
5
|
import { handleLoadModel } from "./load-model/index.js";
|
|
6
|
+
import { ModelLoadFailedError, DelegateNoFinalResponseError, } from "../../../utils/errors-server.js";
|
|
5
7
|
export async function handleLoadModelDelegated(request, progressCallback) {
|
|
6
8
|
if (!request.delegate) {
|
|
7
|
-
throw new
|
|
9
|
+
throw new ModelLoadFailedError("Delegate information is required for delegated load model");
|
|
8
10
|
}
|
|
9
11
|
const { delegate } = request;
|
|
10
12
|
const { topic, providerPublicKey, timeout, fallbackToLocal } = delegate;
|
|
@@ -33,7 +35,7 @@ export async function handleLoadModelDelegated(request, progressCallback) {
|
|
|
33
35
|
}
|
|
34
36
|
}
|
|
35
37
|
if (!finalResponse) {
|
|
36
|
-
throw new
|
|
38
|
+
throw new DelegateNoFinalResponseError();
|
|
37
39
|
}
|
|
38
40
|
}
|
|
39
41
|
else {
|
|
@@ -49,8 +51,9 @@ export async function handleLoadModelDelegated(request, progressCallback) {
|
|
|
49
51
|
error: `Provider failed to load model: ${finalResponse?.error || "Unknown error"}`,
|
|
50
52
|
};
|
|
51
53
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
+
const modelId = finalResponse.modelId ||
|
|
55
|
+
modelInputToSrcSchema.parse(request.modelSrc) ||
|
|
56
|
+
`delegated-${Date.now()}`;
|
|
54
57
|
const delegateOptions = {
|
|
55
58
|
topic,
|
|
56
59
|
providerPublicKey,
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { loadModel } from "../../bare/addons/index.js";
|
|
2
2
|
import { resolveModelPath } from "./load-model/resolve.js";
|
|
3
3
|
import { generateShortHash } from "../../utils/index.js";
|
|
4
|
+
import { TTSConfigModelRequiredError, ESpeakDataPathRequiredError, } from "../../../utils/errors-server.js";
|
|
4
5
|
export async function handleLoadModel(request, progressCallback) {
|
|
5
|
-
const { modelSrc, seed, projectionModelSrc, vadModelSrc } = request;
|
|
6
|
+
const { modelSrc, modelName, seed, projectionModelSrc, vadModelSrc, configSrc, } = request;
|
|
7
|
+
const eSpeakDataPath = request.modelType === "tts"
|
|
8
|
+
? request.eSpeakDataPath
|
|
9
|
+
: undefined;
|
|
6
10
|
try {
|
|
7
11
|
const modelPath = await resolveModelPath(modelSrc, progressCallback, seed);
|
|
8
12
|
let projectionModelPath;
|
|
@@ -13,6 +17,17 @@ export async function handleLoadModel(request, progressCallback) {
|
|
|
13
17
|
if (vadModelSrc) {
|
|
14
18
|
vadModelPath = await resolveModelPath(vadModelSrc, progressCallback, seed);
|
|
15
19
|
}
|
|
20
|
+
let ttsConfigModelPath;
|
|
21
|
+
if (configSrc) {
|
|
22
|
+
ttsConfigModelPath = await resolveModelPath(configSrc, progressCallback, seed);
|
|
23
|
+
}
|
|
24
|
+
// For TTS models, ttsConfigModelPath and eSpeakDataPath are required
|
|
25
|
+
if (request.modelType === "tts" && !ttsConfigModelPath) {
|
|
26
|
+
throw new TTSConfigModelRequiredError();
|
|
27
|
+
}
|
|
28
|
+
if (request.modelType === "tts" && !eSpeakDataPath) {
|
|
29
|
+
throw new ESpeakDataPathRequiredError();
|
|
30
|
+
}
|
|
16
31
|
// Generate hash-based modelId
|
|
17
32
|
const configStr = JSON.stringify(request.modelConfig, Object.keys(request.modelConfig).sort());
|
|
18
33
|
const modelHashInput = `${request.modelType}:${modelSrc}:${configStr}`;
|
|
@@ -23,6 +38,9 @@ export async function handleLoadModel(request, progressCallback) {
|
|
|
23
38
|
options: request,
|
|
24
39
|
projectionModelPath,
|
|
25
40
|
vadModelPath,
|
|
41
|
+
ttsConfigModelPath,
|
|
42
|
+
eSpeakDataPath,
|
|
43
|
+
modelName,
|
|
26
44
|
});
|
|
27
45
|
return {
|
|
28
46
|
type: "loadModel",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getSwarm } from "../../../bare/hyperswarm.js";
|
|
1
|
+
import { getSwarm, registerProviderTopic } from "../../../bare/hyperswarm.js";
|
|
2
2
|
import { setupConnectionHandlers } from "./connection.js";
|
|
3
3
|
export async function provideHandler(request) {
|
|
4
4
|
const swarm = getSwarm({
|
|
@@ -27,6 +27,7 @@ export async function provideHandler(request) {
|
|
|
27
27
|
console.log(`🎯 Ready to accept connections on topic: ${topic.toString("hex").substring(0, 16)}...`);
|
|
28
28
|
// Handle incoming connections
|
|
29
29
|
setupConnectionHandlers(swarm);
|
|
30
|
+
registerProviderTopic(topic.toString("hex"));
|
|
30
31
|
console.log("🏁 About to return success response...");
|
|
31
32
|
const response = {
|
|
32
33
|
type: "provide",
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { setSDKConfig } from "../../bare/registry/config-registry.js";
|
|
2
|
+
export const handleSetConfig = (request) => {
|
|
3
|
+
try {
|
|
4
|
+
setSDKConfig(request.config);
|
|
5
|
+
return {
|
|
6
|
+
type: "setConfig",
|
|
7
|
+
success: true,
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
catch (error) {
|
|
11
|
+
console.error("Error setting config:", error);
|
|
12
|
+
return {
|
|
13
|
+
type: "setConfig",
|
|
14
|
+
success: false,
|
|
15
|
+
error: error instanceof Error ? error.message : "Unknown error",
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { getSwarm, unregisterProviderTopic } from "../../bare/hyperswarm.js";
|
|
2
|
+
export function stopProvideHandler(request) {
|
|
3
|
+
const swarm = getSwarm();
|
|
4
|
+
try {
|
|
5
|
+
const topic = Buffer.from(request.topic, "hex");
|
|
6
|
+
const topicHex = request.topic;
|
|
7
|
+
swarm.leave(topic);
|
|
8
|
+
unregisterProviderTopic(topicHex);
|
|
9
|
+
return {
|
|
10
|
+
type: "stopProvide",
|
|
11
|
+
success: true,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
console.error("❌ Error in stop provide handler:", error);
|
|
16
|
+
return {
|
|
17
|
+
type: "stopProvide",
|
|
18
|
+
success: false,
|
|
19
|
+
error: error instanceof Error ? error.message : "Unknown error",
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { transcribeStream } from "../../bare/addons/whispercpp/index.js";
|
|
2
2
|
export async function* handleTranscribeStream(request) {
|
|
3
|
-
const { modelId, audioChunk } = request;
|
|
3
|
+
const { modelId, audioChunk, prompt } = request;
|
|
4
4
|
try {
|
|
5
5
|
// Stream transcription results in real-time
|
|
6
|
-
for await (const textChunk of transcribeStream({
|
|
6
|
+
for await (const textChunk of transcribeStream({
|
|
7
|
+
audioChunk,
|
|
8
|
+
modelId,
|
|
9
|
+
prompt,
|
|
10
|
+
})) {
|
|
7
11
|
yield {
|
|
8
12
|
type: "transcribeStream",
|
|
9
13
|
text: textChunk,
|
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
import { unloadModel } from "../../bare/addons/index.js";
|
|
2
|
+
import { getRegistryStats } from "../../bare/registry/model-registry.js";
|
|
3
|
+
import { hasActiveProviders } from "../../bare/hyperswarm.js";
|
|
2
4
|
export async function handleUnloadModel(request) {
|
|
3
5
|
const { modelId, clearStorage } = request;
|
|
4
6
|
try {
|
|
5
7
|
console.log("Unloading model", modelId);
|
|
6
8
|
await unloadModel({ modelId, clearStorage });
|
|
9
|
+
const stats = getRegistryStats();
|
|
10
|
+
const modelsActive = stats.totalModels > 0;
|
|
11
|
+
const providersActive = hasActiveProviders();
|
|
7
12
|
return {
|
|
8
13
|
type: "unloadModel",
|
|
9
14
|
success: true,
|
|
15
|
+
hasActiveModels: modelsActive,
|
|
16
|
+
hasActiveProviders: providersActive,
|
|
10
17
|
};
|
|
11
18
|
}
|
|
12
19
|
catch (error) {
|
|
@@ -1,15 +1,20 @@
|
|
|
1
|
+
import type { ShardMetadata } from "./shard-utils";
|
|
2
|
+
export declare const getCacheDir: (subDir: string) => string;
|
|
3
|
+
export declare const getModelsCacheDir: () => string;
|
|
4
|
+
export declare const getKVCacheDir: () => string;
|
|
1
5
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* @returns Full path to the cache directory
|
|
6
|
+
* Get cache directory for sharded model
|
|
7
|
+
* Returns: cache/sharded/<hyperdriveKey>/
|
|
5
8
|
*/
|
|
6
|
-
export declare function
|
|
9
|
+
export declare function getShardedModelCacheDir(hyperdriveKey: string): string;
|
|
7
10
|
/**
|
|
8
|
-
*
|
|
11
|
+
* Get full path to specific shard file
|
|
12
|
+
* Returns: cache/sharded/<hyperdriveKey>/<shardFilename>
|
|
9
13
|
*/
|
|
10
|
-
export declare function
|
|
14
|
+
export declare function getShardPath(hyperdriveKey: string, shardFilename: string): string;
|
|
11
15
|
/**
|
|
12
|
-
*
|
|
16
|
+
* Check if all shards exist and are valid (size + checksum check)
|
|
17
|
+
* Returns array of missing/invalid shard indices (0-based)
|
|
13
18
|
*/
|
|
14
|
-
export declare function
|
|
19
|
+
export declare function checkShardCompleteness(hyperdriveKey: string, shardFilenames: readonly string[], shardMetadata: readonly ShardMetadata[]): Promise<number[]>;
|
|
15
20
|
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -1,15 +1,11 @@
|
|
|
1
|
-
import fs from "bare-fs";
|
|
1
|
+
import fs, { promises as fsPromises } from "bare-fs";
|
|
2
2
|
import path from "bare-path";
|
|
3
3
|
import { getEnv } from "../worker.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
* @returns Full path to the cache directory
|
|
8
|
-
*/
|
|
9
|
-
export function getCacheDir(subDir) {
|
|
4
|
+
import { getConfiguredCacheDir } from "../bare/registry/config-registry.js";
|
|
5
|
+
import { calculateFileChecksum } from "./checksum.js";
|
|
6
|
+
export const getCacheDir = (subDir) => {
|
|
10
7
|
const homeDir = getEnv().HOME_DIR;
|
|
11
8
|
const cacheDir = path.join(homeDir, ".qvac", subDir);
|
|
12
|
-
// Ensure cache directory exists
|
|
13
9
|
try {
|
|
14
10
|
fs.mkdirSync(cacheDir, { recursive: true });
|
|
15
11
|
}
|
|
@@ -17,16 +13,75 @@ export function getCacheDir(subDir) {
|
|
|
17
13
|
console.error(`Error creating cache directory (${subDir}):`, error instanceof Error ? error.message : String(error));
|
|
18
14
|
}
|
|
19
15
|
return cacheDir;
|
|
16
|
+
};
|
|
17
|
+
export const getModelsCacheDir = () => {
|
|
18
|
+
const configuredDir = getConfiguredCacheDir();
|
|
19
|
+
try {
|
|
20
|
+
fs.mkdirSync(configuredDir, { recursive: true });
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
console.error(`Error creating models cache directory:`, error instanceof Error ? error.message : String(error));
|
|
24
|
+
}
|
|
25
|
+
return configuredDir;
|
|
26
|
+
};
|
|
27
|
+
export const getKVCacheDir = () => {
|
|
28
|
+
return getCacheDir("kv-cache");
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Get cache directory for sharded model
|
|
32
|
+
* Returns: cache/sharded/<hyperdriveKey>/
|
|
33
|
+
*/
|
|
34
|
+
export function getShardedModelCacheDir(hyperdriveKey) {
|
|
35
|
+
const baseCache = getModelsCacheDir();
|
|
36
|
+
const shardDir = path.join(baseCache, "sharded", hyperdriveKey);
|
|
37
|
+
try {
|
|
38
|
+
fs.mkdirSync(shardDir, { recursive: true });
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
console.error(`Error creating sharded model cache directory:`, error instanceof Error ? error.message : String(error));
|
|
42
|
+
}
|
|
43
|
+
return shardDir;
|
|
20
44
|
}
|
|
21
45
|
/**
|
|
22
|
-
*
|
|
46
|
+
* Get full path to specific shard file
|
|
47
|
+
* Returns: cache/sharded/<hyperdriveKey>/<shardFilename>
|
|
23
48
|
*/
|
|
24
|
-
export function
|
|
25
|
-
|
|
49
|
+
export function getShardPath(hyperdriveKey, shardFilename) {
|
|
50
|
+
const shardDir = getShardedModelCacheDir(hyperdriveKey);
|
|
51
|
+
return path.join(shardDir, shardFilename);
|
|
26
52
|
}
|
|
27
53
|
/**
|
|
28
|
-
*
|
|
54
|
+
* Check if all shards exist and are valid (size + checksum check)
|
|
55
|
+
* Returns array of missing/invalid shard indices (0-based)
|
|
29
56
|
*/
|
|
30
|
-
export function
|
|
31
|
-
|
|
57
|
+
export async function checkShardCompleteness(hyperdriveKey, shardFilenames, shardMetadata) {
|
|
58
|
+
const invalidIndices = [];
|
|
59
|
+
for (let i = 0; i < shardFilenames.length; i++) {
|
|
60
|
+
const shardPath = getShardPath(hyperdriveKey, shardFilenames[i]);
|
|
61
|
+
const fileMeta = shardMetadata[i];
|
|
62
|
+
if (!fileMeta) {
|
|
63
|
+
invalidIndices.push(i);
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
const stats = await fsPromises.stat(shardPath);
|
|
68
|
+
if (stats.size !== fileMeta.expectedSize) {
|
|
69
|
+
console.warn(`File ${i + 1} size mismatch: expected ${fileMeta.expectedSize}, got ${stats.size}`);
|
|
70
|
+
invalidIndices.push(i);
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (fileMeta.sha256Checksum) {
|
|
74
|
+
const actualChecksum = await calculateFileChecksum(shardPath);
|
|
75
|
+
if (actualChecksum !== fileMeta.sha256Checksum) {
|
|
76
|
+
console.warn(`File ${i + 1} checksum mismatch for ${fileMeta.filename}. Expected: ${fileMeta.sha256Checksum}. Actual: ${actualChecksum}. Will re-download.`);
|
|
77
|
+
invalidIndices.push(i);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
// File doesn't exist
|
|
83
|
+
invalidIndices.push(i);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return invalidIndices;
|
|
32
87
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import fs from "bare-fs";
|
|
2
|
+
import crypto from "bare-crypto";
|
|
3
|
+
export async function calculateFileChecksum(filePath) {
|
|
4
|
+
return new Promise((resolve, reject) => {
|
|
5
|
+
try {
|
|
6
|
+
const hash = crypto.createHash("sha256");
|
|
7
|
+
const stream = fs.createReadStream(filePath);
|
|
8
|
+
stream.on("data", (chunk) => {
|
|
9
|
+
hash.update(chunk);
|
|
10
|
+
});
|
|
11
|
+
stream.on("end", () => {
|
|
12
|
+
resolve(hash.digest("hex"));
|
|
13
|
+
});
|
|
14
|
+
stream.on("error", (error) => {
|
|
15
|
+
reject(new Error(`Checksum calculation error: ${error.message}`));
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
reject(error instanceof Error
|
|
20
|
+
? error
|
|
21
|
+
: new Error(`Checksum calculation error: ${String(error)}`));
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface ShardInfo {
|
|
2
|
+
isSharded: boolean;
|
|
3
|
+
currentShard?: number;
|
|
4
|
+
totalShards?: number;
|
|
5
|
+
baseFilename?: string;
|
|
6
|
+
extension?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ShardMetadata {
|
|
9
|
+
filename: string;
|
|
10
|
+
expectedSize: number;
|
|
11
|
+
sha256Checksum: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Detect if model filename follows shard pattern (00001-of-0000x)
|
|
15
|
+
*/
|
|
16
|
+
export declare function detectShardedModel(filename: string): ShardInfo;
|
|
17
|
+
/**
|
|
18
|
+
* Generate list of all required files for a sharded model
|
|
19
|
+
* Includes numbered shards AND the .tensors.txt companion file
|
|
20
|
+
*/
|
|
21
|
+
export declare function generateShardFilenames(firstShardName: string): string[];
|
|
22
|
+
//# sourceMappingURL=shard-utils.d.ts.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { ModelLoadFailedError } from "../../utils/errors-server.js";
|
|
2
|
+
/**
|
|
3
|
+
* Detect if model filename follows shard pattern (00001-of-0000x)
|
|
4
|
+
*/
|
|
5
|
+
export function detectShardedModel(filename) {
|
|
6
|
+
const shardPattern = /^(.+)-(\d{5})-of-(\d{5})(\.\w+)$/;
|
|
7
|
+
const match = filename.match(shardPattern);
|
|
8
|
+
if (match && match[1] && match[2] && match[3] && match[4]) {
|
|
9
|
+
return {
|
|
10
|
+
isSharded: true,
|
|
11
|
+
baseFilename: match[1],
|
|
12
|
+
currentShard: parseInt(match[2], 10),
|
|
13
|
+
totalShards: parseInt(match[3], 10),
|
|
14
|
+
extension: match[4],
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
return { isSharded: false };
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Generate list of all required files for a sharded model
|
|
21
|
+
* Includes numbered shards AND the .tensors.txt companion file
|
|
22
|
+
*/
|
|
23
|
+
export function generateShardFilenames(firstShardName) {
|
|
24
|
+
const shardInfo = detectShardedModel(firstShardName);
|
|
25
|
+
if (!shardInfo.isSharded || !shardInfo.totalShards) {
|
|
26
|
+
throw new ModelLoadFailedError(`Not a sharded model filename: ${firstShardName}`);
|
|
27
|
+
}
|
|
28
|
+
const filenames = [];
|
|
29
|
+
const { baseFilename, totalShards, extension } = shardInfo;
|
|
30
|
+
for (let i = 1; i <= totalShards; i++) {
|
|
31
|
+
const shardNumber = i.toString().padStart(5, "0");
|
|
32
|
+
const totalShardsStr = totalShards.toString().padStart(5, "0");
|
|
33
|
+
filenames.push(`${baseFilename}-${shardNumber}-of-${totalShardsStr}${extension}`);
|
|
34
|
+
}
|
|
35
|
+
filenames.push(`${baseFilename}.tensors.txt`);
|
|
36
|
+
return filenames;
|
|
37
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Tool, ToolCallEvent } from "../../schemas/index";
|
|
2
|
+
interface HistoryMessage {
|
|
3
|
+
role: string;
|
|
4
|
+
content: string;
|
|
5
|
+
attachments?: {
|
|
6
|
+
path: string;
|
|
7
|
+
}[] | undefined;
|
|
8
|
+
}
|
|
9
|
+
export declare function insertToolsIntoHistory(history: HistoryMessage[], tools: Tool[]): Array<HistoryMessage | Tool>;
|
|
10
|
+
export declare function setupToolGrammar(modelConfig: Record<string, unknown>, tools: Tool[]): void;
|
|
11
|
+
export declare function checkForToolEvents(accumulatedText: string, currentToken: string, tools: Tool[], emittedToolCallPositions: Set<number>): ToolCallEvent[];
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=tool-integration.d.ts.map
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { parseToolCalls, convertToolsToGrammar, } from "./tool-parser.js";
|
|
2
|
+
export function insertToolsIntoHistory(history, tools) {
|
|
3
|
+
const systemMsgIndex = history.findIndex((msg) => msg.role === "system");
|
|
4
|
+
if (systemMsgIndex >= 0) {
|
|
5
|
+
return [
|
|
6
|
+
...history.slice(0, systemMsgIndex + 1),
|
|
7
|
+
...tools,
|
|
8
|
+
...history.slice(systemMsgIndex + 1),
|
|
9
|
+
];
|
|
10
|
+
}
|
|
11
|
+
return [...tools, ...history];
|
|
12
|
+
}
|
|
13
|
+
export function setupToolGrammar(modelConfig, tools) {
|
|
14
|
+
const grammar = convertToolsToGrammar(tools);
|
|
15
|
+
modelConfig["grammar"] = grammar;
|
|
16
|
+
}
|
|
17
|
+
export function checkForToolEvents(accumulatedText, currentToken, tools, emittedToolCallPositions) {
|
|
18
|
+
const events = [];
|
|
19
|
+
if (currentToken.includes("</tool_call>") || currentToken.includes("}")) {
|
|
20
|
+
const { toolCalls, errors } = parseToolCalls(accumulatedText, tools);
|
|
21
|
+
for (const call of toolCalls) {
|
|
22
|
+
const callPosition = accumulatedText.indexOf(call.raw || "");
|
|
23
|
+
if (callPosition >= 0 && !emittedToolCallPositions.has(callPosition)) {
|
|
24
|
+
emittedToolCallPositions.add(callPosition);
|
|
25
|
+
events.push({
|
|
26
|
+
type: "toolCall",
|
|
27
|
+
call,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
for (const error of errors) {
|
|
32
|
+
const errorPosition = accumulatedText.indexOf(error.raw || "");
|
|
33
|
+
if (errorPosition >= 0 && !emittedToolCallPositions.has(errorPosition)) {
|
|
34
|
+
emittedToolCallPositions.add(errorPosition);
|
|
35
|
+
events.push({
|
|
36
|
+
type: "toolCallError",
|
|
37
|
+
error,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return events;
|
|
43
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Tool, ToolCall, ToolCallError } from "../../schemas/index";
|
|
2
|
+
export declare function parseToolCalls(text: string, tools: Tool[]): {
|
|
3
|
+
toolCalls: ToolCall[];
|
|
4
|
+
errors: ToolCallError[];
|
|
5
|
+
};
|
|
6
|
+
export declare function convertToolsToGrammar(tools: Tool[]): string;
|
|
7
|
+
//# sourceMappingURL=tool-parser.d.ts.map
|