@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
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { getCachedConfig } from "./config-manager.js";
|
|
2
|
+
/**
|
|
3
|
+
* Replays cached configuration to the worker after initialization.
|
|
4
|
+
* This ensures config persists across worker restarts.
|
|
5
|
+
*/
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
7
|
+
export const replayConfigIfCached = async (rpc) => {
|
|
8
|
+
const config = getCachedConfig();
|
|
9
|
+
if (!config) {
|
|
10
|
+
console.log("No cached config to replay");
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
console.log("🔄 Replaying cached config to worker:", config);
|
|
14
|
+
try {
|
|
15
|
+
const request = {
|
|
16
|
+
type: "setConfig",
|
|
17
|
+
config,
|
|
18
|
+
};
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
20
|
+
const req = rpc.request(1);
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
22
|
+
req.send(JSON.stringify(request), "utf8");
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
24
|
+
const response = await req.reply("utf8");
|
|
25
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
|
26
|
+
const parsed = JSON.parse(response.toString());
|
|
27
|
+
if (parsed.type !== "setConfig" || !parsed.success) {
|
|
28
|
+
console.error("Failed to replay config:", parsed.error);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
console.log("✅ Config successfully replayed to worker");
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
console.error("Error replaying config:", error);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
@@ -13,17 +13,51 @@ export declare function stream<T extends Request>(request: T): AsyncGenerator<{
|
|
|
13
13
|
tokensPerSecond: number;
|
|
14
14
|
cacheTokens: number;
|
|
15
15
|
} | undefined;
|
|
16
|
+
toolCallEvent?: {
|
|
17
|
+
type: "toolCall";
|
|
18
|
+
call: {
|
|
19
|
+
id: string;
|
|
20
|
+
name: string;
|
|
21
|
+
arguments: Record<string, unknown>;
|
|
22
|
+
raw?: string | undefined;
|
|
23
|
+
};
|
|
24
|
+
} | {
|
|
25
|
+
type: "toolCallError";
|
|
26
|
+
error: {
|
|
27
|
+
code: "PARSE_ERROR" | "VALIDATION_ERROR" | "UNKNOWN_TOOL";
|
|
28
|
+
message: string;
|
|
29
|
+
raw?: string | undefined;
|
|
30
|
+
};
|
|
31
|
+
} | undefined;
|
|
32
|
+
toolCalls?: {
|
|
33
|
+
id: string;
|
|
34
|
+
name: string;
|
|
35
|
+
arguments: Record<string, unknown>;
|
|
36
|
+
raw?: string | undefined;
|
|
37
|
+
}[] | undefined;
|
|
16
38
|
error?: string | undefined;
|
|
17
39
|
} | {
|
|
18
40
|
type: "deleteCache";
|
|
19
41
|
success: boolean;
|
|
20
42
|
error?: string | undefined;
|
|
43
|
+
} | {
|
|
44
|
+
type: "textToSpeech";
|
|
45
|
+
buffer: number[];
|
|
46
|
+
done: boolean;
|
|
21
47
|
} | {
|
|
22
48
|
type: "modelProgress";
|
|
23
49
|
downloaded: number;
|
|
24
50
|
total: number;
|
|
25
51
|
percentage: number;
|
|
26
52
|
downloadKey: string;
|
|
53
|
+
shardInfo?: {
|
|
54
|
+
currentShard: number;
|
|
55
|
+
totalShards: number;
|
|
56
|
+
shardName: string;
|
|
57
|
+
overallDownloaded: number;
|
|
58
|
+
overallTotal: number;
|
|
59
|
+
overallPercentage: number;
|
|
60
|
+
} | undefined;
|
|
27
61
|
} | {
|
|
28
62
|
type: "loadModel";
|
|
29
63
|
success: boolean;
|
|
@@ -59,6 +93,8 @@ export declare function stream<T extends Request>(request: T): AsyncGenerator<{
|
|
|
59
93
|
type: "unloadModel";
|
|
60
94
|
success: boolean;
|
|
61
95
|
error?: string | undefined;
|
|
96
|
+
hasActiveModels?: boolean | undefined;
|
|
97
|
+
hasActiveProviders?: boolean | undefined;
|
|
62
98
|
} | {
|
|
63
99
|
type: "pong";
|
|
64
100
|
number: number;
|
|
@@ -110,6 +146,39 @@ export declare function stream<T extends Request>(request: T): AsyncGenerator<{
|
|
|
110
146
|
success: boolean;
|
|
111
147
|
operation: "deleteEmbeddings";
|
|
112
148
|
error?: string | undefined;
|
|
149
|
+
} | {
|
|
150
|
+
type: "setConfig";
|
|
151
|
+
success: boolean;
|
|
152
|
+
error?: string | undefined;
|
|
153
|
+
} | {
|
|
154
|
+
type: "getModelInfo";
|
|
155
|
+
modelInfo: {
|
|
156
|
+
name: string;
|
|
157
|
+
modelId: string;
|
|
158
|
+
hyperdriveKey: string;
|
|
159
|
+
hyperbeeKey: string;
|
|
160
|
+
expectedSize: number;
|
|
161
|
+
sha256Checksum: string;
|
|
162
|
+
addon: "llm" | "whisper" | "embeddings" | "nmt" | "vad" | "tts";
|
|
163
|
+
isCached: boolean;
|
|
164
|
+
isLoaded: boolean;
|
|
165
|
+
cacheFiles: {
|
|
166
|
+
filename: string;
|
|
167
|
+
path: string;
|
|
168
|
+
expectedSize: number;
|
|
169
|
+
sha256Checksum: string;
|
|
170
|
+
isCached: boolean;
|
|
171
|
+
actualSize?: number | undefined;
|
|
172
|
+
cachedAt?: Date | undefined;
|
|
173
|
+
}[];
|
|
174
|
+
actualSize?: number | undefined;
|
|
175
|
+
cachedAt?: Date | undefined;
|
|
176
|
+
loadedInstances?: {
|
|
177
|
+
registryId: string;
|
|
178
|
+
loadedAt: Date;
|
|
179
|
+
config?: unknown;
|
|
180
|
+
}[] | undefined;
|
|
181
|
+
};
|
|
113
182
|
}, void, any>;
|
|
114
183
|
export declare function getRPC(): {
|
|
115
184
|
request(): {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { handlers } from "../../server/rpc/handlers/index.js";
|
|
2
|
+
import { RPCNoHandlerError, RPCRequestNotSentError, } from "../../utils/errors-client.js";
|
|
2
3
|
// Get the handler for a request type
|
|
3
4
|
const getHandler = (type) => {
|
|
4
5
|
const handler = handlers[type];
|
|
@@ -10,13 +11,13 @@ export async function send(request) {
|
|
|
10
11
|
}
|
|
11
12
|
const handler = getHandler(request.type);
|
|
12
13
|
if (!handler)
|
|
13
|
-
throw new
|
|
14
|
+
throw new RPCNoHandlerError(request.type);
|
|
14
15
|
return (await handler(request));
|
|
15
16
|
}
|
|
16
17
|
export async function* stream(request) {
|
|
17
18
|
const handler = getHandler(request.type);
|
|
18
19
|
if (!handler)
|
|
19
|
-
throw new
|
|
20
|
+
throw new RPCNoHandlerError(request.type);
|
|
20
21
|
// Special handling for loadModel with progress
|
|
21
22
|
if (request.type === "loadModel" &&
|
|
22
23
|
"withProgress" in request &&
|
|
@@ -94,14 +95,14 @@ const createMockRPCRequest = () => {
|
|
|
94
95
|
},
|
|
95
96
|
async reply() {
|
|
96
97
|
if (!requestData) {
|
|
97
|
-
throw new
|
|
98
|
+
throw new RPCRequestNotSentError();
|
|
98
99
|
}
|
|
99
100
|
const response = await send(requestData);
|
|
100
101
|
return Buffer.from(JSON.stringify(response));
|
|
101
102
|
},
|
|
102
103
|
async *createResponseStream() {
|
|
103
104
|
if (!requestData) {
|
|
104
|
-
throw new
|
|
105
|
+
throw new RPCRequestNotSentError();
|
|
105
106
|
}
|
|
106
107
|
for await (const response of stream(requestData)) {
|
|
107
108
|
yield Buffer.from(JSON.stringify(response) + "\n");
|
|
@@ -23,10 +23,10 @@ else {
|
|
|
23
23
|
WORKER_PATH = path.resolve(cwd, "dist/server/worker.js");
|
|
24
24
|
}
|
|
25
25
|
const SOCKET_PATH = path.join(os.tmpdir(), `qvac-worker-${process.pid}.sock`);
|
|
26
|
-
export function getRPC() {
|
|
26
|
+
export async function getRPC() {
|
|
27
27
|
if (rpcInstance) {
|
|
28
28
|
console.log("returning cached bare rpc");
|
|
29
|
-
return
|
|
29
|
+
return rpcInstance;
|
|
30
30
|
}
|
|
31
31
|
console.log("initRPC for bare runtime with socket:", SOCKET_PATH);
|
|
32
32
|
// Start IPC server (Unix socket)
|
|
@@ -71,7 +71,11 @@ export function getRPC() {
|
|
|
71
71
|
});
|
|
72
72
|
});
|
|
73
73
|
});
|
|
74
|
-
|
|
74
|
+
// Wait for RPC to initialize, then replay config
|
|
75
|
+
const rpc = await serverPromise;
|
|
76
|
+
const { replayConfigIfCached } = await import("../init-hooks.js");
|
|
77
|
+
await replayConfigIfCached(rpc);
|
|
78
|
+
return rpc;
|
|
75
79
|
}
|
|
76
80
|
// Clean up function
|
|
77
81
|
export const cleanup = () => {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import RPC from "bare-rpc";
|
|
2
|
+
import { RPCConnectionFailedError } from "../../utils/errors-client.js";
|
|
2
3
|
let rpcInstance = null;
|
|
3
4
|
let rpcPromise = null;
|
|
4
5
|
console.log("EXPO RPC Client bundle");
|
|
@@ -28,7 +29,7 @@ export const getRPC = async () => {
|
|
|
28
29
|
`Add '@qvac/sdk/expo-plugin' to your app.json plugins array. ` +
|
|
29
30
|
`Error: ${String(error)}`;
|
|
30
31
|
console.error(message);
|
|
31
|
-
throw new
|
|
32
|
+
throw new RPCConnectionFailedError(message, error instanceof Error ? error : undefined);
|
|
32
33
|
}
|
|
33
34
|
worklet.start("worker.bundle", mobileBundle, [
|
|
34
35
|
// Normalize arg number across platforms
|
|
@@ -42,6 +43,8 @@ export const getRPC = async () => {
|
|
|
42
43
|
rpcInstance = new RPC(worklet.IPC, () => {
|
|
43
44
|
// Use this for async callbacks
|
|
44
45
|
});
|
|
46
|
+
const { replayConfigIfCached } = await import("../init-hooks.js");
|
|
47
|
+
await replayConfigIfCached(rpcInstance);
|
|
45
48
|
return rpcInstance;
|
|
46
49
|
})();
|
|
47
50
|
try {
|
|
@@ -55,3 +58,8 @@ export const getRPC = async () => {
|
|
|
55
58
|
rpcPromise = null;
|
|
56
59
|
}
|
|
57
60
|
};
|
|
61
|
+
export const close = () => {
|
|
62
|
+
console.log("🧹 Closing RPC client (Expo)");
|
|
63
|
+
rpcInstance = null;
|
|
64
|
+
rpcPromise = null;
|
|
65
|
+
};
|
|
@@ -4,11 +4,13 @@ import { createServer } from "node:net";
|
|
|
4
4
|
import os from "node:os";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
|
+
import { RPCRequestNotSentError } from "../../utils/errors-client.js";
|
|
7
8
|
const __filename = fileURLToPath(import.meta.url);
|
|
8
9
|
const __dirname = path.dirname(__filename);
|
|
9
10
|
let rpcInstance = null;
|
|
10
11
|
let rpcPromise = null;
|
|
11
12
|
let bareWorkerProc = null;
|
|
13
|
+
let ipcServer = null;
|
|
12
14
|
// Smart path resolution for worker
|
|
13
15
|
let WORKER_PATH;
|
|
14
16
|
if (__dirname.includes("/dist/") || __dirname.includes("\\dist\\")) {
|
|
@@ -29,12 +31,12 @@ async function ensureRPC() {
|
|
|
29
31
|
if (rpcPromise)
|
|
30
32
|
return rpcPromise;
|
|
31
33
|
rpcPromise = new Promise((resolve, reject) => {
|
|
32
|
-
|
|
34
|
+
ipcServer = createServer((socket) => {
|
|
33
35
|
rpcInstance = new RPC(socket, () => { });
|
|
34
36
|
resolve(rpcInstance);
|
|
35
37
|
});
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
ipcServer.on("error", reject);
|
|
39
|
+
ipcServer.listen(SOCKET_PATH, () => {
|
|
38
40
|
bareWorkerProc = spawn("bare", {
|
|
39
41
|
args: [
|
|
40
42
|
WORKER_PATH,
|
|
@@ -47,7 +49,10 @@ async function ensureRPC() {
|
|
|
47
49
|
});
|
|
48
50
|
});
|
|
49
51
|
});
|
|
50
|
-
|
|
52
|
+
const rpc = await rpcPromise;
|
|
53
|
+
const { replayConfigIfCached } = await import("../init-hooks.js");
|
|
54
|
+
await replayConfigIfCached(rpc);
|
|
55
|
+
return rpc;
|
|
51
56
|
}
|
|
52
57
|
const mockRPC = {
|
|
53
58
|
request: (command) => {
|
|
@@ -58,7 +63,7 @@ const mockRPC = {
|
|
|
58
63
|
},
|
|
59
64
|
reply: async (encoding) => {
|
|
60
65
|
if (!sentData) {
|
|
61
|
-
throw new
|
|
66
|
+
throw new RPCRequestNotSentError();
|
|
62
67
|
}
|
|
63
68
|
const rpc = await ensureRPC();
|
|
64
69
|
const req = rpc.request(command);
|
|
@@ -70,7 +75,7 @@ const mockRPC = {
|
|
|
70
75
|
},
|
|
71
76
|
createResponseStream: async function* () {
|
|
72
77
|
if (!sentData) {
|
|
73
|
-
throw new
|
|
78
|
+
throw new RPCRequestNotSentError();
|
|
74
79
|
}
|
|
75
80
|
const rpc = await ensureRPC();
|
|
76
81
|
const req = rpc.request(command);
|
|
@@ -88,12 +93,20 @@ const mockRPC = {
|
|
|
88
93
|
export function getRPC() {
|
|
89
94
|
return mockRPC;
|
|
90
95
|
}
|
|
91
|
-
export const
|
|
92
|
-
console.log("🧹
|
|
96
|
+
export const close = () => {
|
|
97
|
+
console.log("🧹 Closing RPC client");
|
|
93
98
|
if (bareWorkerProc) {
|
|
94
99
|
console.log("🐻🔫 Killing bare worker process");
|
|
95
100
|
bareWorkerProc.kill("SIGTERM");
|
|
101
|
+
bareWorkerProc = null;
|
|
96
102
|
}
|
|
103
|
+
if (ipcServer) {
|
|
104
|
+
console.log("🔌 Closing IPC server");
|
|
105
|
+
ipcServer.close();
|
|
106
|
+
ipcServer = null;
|
|
107
|
+
}
|
|
108
|
+
rpcInstance = null;
|
|
109
|
+
rpcPromise = null;
|
|
97
110
|
};
|
|
98
111
|
// Register cleanup handlers for the parent process
|
|
99
|
-
process.once("exit",
|
|
112
|
+
process.once("exit", close);
|
|
@@ -2,4 +2,5 @@ import type RPC from "bare-rpc";
|
|
|
2
2
|
import { type Request, type Response, type RPCOptions } from "../../schemas/index";
|
|
3
3
|
export declare function send<T extends Request>(request: T, rpc?: RPC, options?: RPCOptions): Promise<Response>;
|
|
4
4
|
export declare function stream<T extends Request>(request: T, rpc?: RPC, options?: RPCOptions): AsyncGenerator<Response>;
|
|
5
|
+
export declare function close(): Promise<void>;
|
|
5
6
|
//# sourceMappingURL=rpc-client.d.ts.map
|
|
@@ -53,7 +53,8 @@ export async function send(request, rpc, options) {
|
|
|
53
53
|
console.log("RPC Client sending:", {
|
|
54
54
|
type: request.type,
|
|
55
55
|
modelId: request.modelId,
|
|
56
|
-
|
|
56
|
+
audioChunkType: request.audioChunk.type,
|
|
57
|
+
audioChunkSize: request.audioChunk.value.length,
|
|
57
58
|
});
|
|
58
59
|
}
|
|
59
60
|
else {
|
|
@@ -94,3 +95,21 @@ export async function* stream(request, rpc, options = {}) {
|
|
|
94
95
|
}
|
|
95
96
|
}
|
|
96
97
|
}
|
|
98
|
+
export async function close() {
|
|
99
|
+
if (!rpcInstance)
|
|
100
|
+
return;
|
|
101
|
+
const isRN = typeof navigator !== "undefined" && navigator.product === "ReactNative";
|
|
102
|
+
const isBare = typeof globalThis !== "undefined" && "Bare" in globalThis;
|
|
103
|
+
if (isRN) {
|
|
104
|
+
const mod = (await import("./expo-rpc-client.js"));
|
|
105
|
+
mod.close();
|
|
106
|
+
}
|
|
107
|
+
else if (isBare) {
|
|
108
|
+
// Bare runs in-process (no separate worker), so no cleanup needed
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
const mod = (await import("./node-rpc-client.js"));
|
|
112
|
+
mod.close();
|
|
113
|
+
}
|
|
114
|
+
rpcInstance = null;
|
|
115
|
+
}
|
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
export
|
|
2
|
-
export declare const SUPPORTED_AUDIO_FORMATS: readonly [".mp3", ".m4a", ".ogg", ".wav", ".flac", ".aac", ".raw"];
|
|
1
|
+
export { FORMATS_NEEDING_DECODE, SUPPORTED_AUDIO_FORMATS, } from "@qvac/decoder-audio/constants";
|
|
3
2
|
//# sourceMappingURL=audio.d.ts.map
|
package/dist/constants/audio.js
CHANGED
|
@@ -1,17 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
".mp3",
|
|
3
|
-
".m4a",
|
|
4
|
-
".ogg",
|
|
5
|
-
".flac",
|
|
6
|
-
".aac",
|
|
7
|
-
".wav",
|
|
8
|
-
];
|
|
9
|
-
export const SUPPORTED_AUDIO_FORMATS = [
|
|
10
|
-
".mp3",
|
|
11
|
-
".m4a",
|
|
12
|
-
".ogg",
|
|
13
|
-
".wav",
|
|
14
|
-
".flac",
|
|
15
|
-
".aac",
|
|
16
|
-
".raw",
|
|
17
|
-
];
|
|
1
|
+
export { FORMATS_NEEDING_DECODE, SUPPORTED_AUDIO_FORMATS, } from "@qvac/decoder-audio/constants.js";
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { WHISPER_TINY } from "../models/hyperdrive/index.js";
|
|
2
|
+
import { downloadAsset, getModelInfo, loadModel, unloadModel } from "..";
|
|
3
|
+
const printModelStatus = (info, label) => {
|
|
4
|
+
console.log(`\n${label}`);
|
|
5
|
+
console.log(` Model Name: ${info.name}`);
|
|
6
|
+
console.log(` Model ID: ${info.modelId}`);
|
|
7
|
+
console.log(` Hyperdrive Key: ${info.hyperdriveKey.substring(0, 16)}...`);
|
|
8
|
+
console.log(` Expected Size: ${(info.expectedSize / 1024 / 1024).toFixed(2)} MB`);
|
|
9
|
+
console.log(` Addon: ${info.addon}`);
|
|
10
|
+
console.log(` Cache Files: ${info.cacheFiles.length}`);
|
|
11
|
+
console.log(` Is Cached: ${info.isCached ? "✅" : "❌"}`);
|
|
12
|
+
console.log(` Is Loaded: ${info.isLoaded ? "✅" : "❌"}`);
|
|
13
|
+
if (info.isCached) {
|
|
14
|
+
if (info.cacheFiles.length === 1) {
|
|
15
|
+
console.log(` Cache Path: ${info.cacheFiles[0]?.path}`);
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
const cachedFiles = info.cacheFiles.filter((f) => f.isCached).length;
|
|
19
|
+
console.log(` Cached: ${cachedFiles}/${info.cacheFiles.length}`);
|
|
20
|
+
}
|
|
21
|
+
console.log(` Actual Size: ${(info.actualSize / 1024 / 1024).toFixed(2)} MB`);
|
|
22
|
+
console.log(` Cached At: ${info.cachedAt?.toLocaleString()}`);
|
|
23
|
+
}
|
|
24
|
+
if (info.loadedInstances && info.loadedInstances.length > 0) {
|
|
25
|
+
console.log(` Loaded Instances: ${info.loadedInstances.length}`);
|
|
26
|
+
info.loadedInstances.forEach((instance, i) => {
|
|
27
|
+
console.log(` ${i + 1}. Registry ID: ${instance.registryId}`);
|
|
28
|
+
console.log(` Loaded At: ${instance.loadedAt.toLocaleString()}`);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
try {
|
|
33
|
+
console.log("=== Model Cache Management Demo ===");
|
|
34
|
+
// 1. Check initial status
|
|
35
|
+
console.log("\n1️⃣ INITIAL STATUS CHECK");
|
|
36
|
+
const initialInfo = await getModelInfo(WHISPER_TINY);
|
|
37
|
+
printModelStatus(initialInfo, "Initial Status:");
|
|
38
|
+
// 2. Download if not cached
|
|
39
|
+
if (!initialInfo.isCached) {
|
|
40
|
+
console.log("\n2️⃣ DOWNLOADING MODEL (not cached)");
|
|
41
|
+
console.log(" Downloading from hyperdrive...");
|
|
42
|
+
await downloadAsset({ assetSrc: WHISPER_TINY });
|
|
43
|
+
console.log(" ✅ Download complete!");
|
|
44
|
+
const afterDownload = await getModelInfo(WHISPER_TINY);
|
|
45
|
+
printModelStatus(afterDownload, "Status After Download:");
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
console.log("\n2️⃣ MODEL ALREADY CACHED");
|
|
49
|
+
console.log(" Skipping download...");
|
|
50
|
+
}
|
|
51
|
+
// 3. Load if not loaded
|
|
52
|
+
console.log("\n3️⃣ LOADING MODEL INTO MEMORY");
|
|
53
|
+
const beforeLoad = await getModelInfo(WHISPER_TINY);
|
|
54
|
+
let modelId;
|
|
55
|
+
if (!beforeLoad.isLoaded) {
|
|
56
|
+
console.log(" Loading model into memory...");
|
|
57
|
+
modelId = await loadModel({
|
|
58
|
+
modelSrc: WHISPER_TINY,
|
|
59
|
+
modelType: "whisper",
|
|
60
|
+
});
|
|
61
|
+
console.log(` ✅ Model loaded! ID: ${modelId}`);
|
|
62
|
+
const afterLoad = await getModelInfo(WHISPER_TINY);
|
|
63
|
+
printModelStatus(afterLoad, "Status After Load:");
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
console.log(" Model already loaded!");
|
|
67
|
+
const instances = beforeLoad.loadedInstances;
|
|
68
|
+
if (!instances || instances.length === 0) {
|
|
69
|
+
throw new Error("Model is loaded but no instances found");
|
|
70
|
+
}
|
|
71
|
+
const firstInstance = instances[0];
|
|
72
|
+
if (!firstInstance) {
|
|
73
|
+
throw new Error("First instance is undefined");
|
|
74
|
+
}
|
|
75
|
+
modelId = firstInstance.registryId;
|
|
76
|
+
console.log(` Using existing model ID: ${modelId}`);
|
|
77
|
+
}
|
|
78
|
+
// 4. Demonstrate unload
|
|
79
|
+
console.log("\n4️⃣ UNLOADING MODEL");
|
|
80
|
+
console.log(" Unloading model from memory...");
|
|
81
|
+
await unloadModel({ modelId });
|
|
82
|
+
console.log(" ✅ Model unloaded!");
|
|
83
|
+
const afterUnload = await getModelInfo(WHISPER_TINY);
|
|
84
|
+
printModelStatus(afterUnload, "Status After Unload:");
|
|
85
|
+
// 5. Summary
|
|
86
|
+
console.log("\n5️⃣ SUMMARY");
|
|
87
|
+
console.log(" ✅ Model Info API works correctly");
|
|
88
|
+
console.log(" ✅ Cache status tracked accurately");
|
|
89
|
+
console.log(" ✅ Loaded status reflects memory state");
|
|
90
|
+
console.log(" ✅ All operations completed successfully");
|
|
91
|
+
console.log("\n=== Demo Complete ===\n");
|
|
92
|
+
process.exit(0);
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
console.error("❌ Error:", error);
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { completion, LLAMA_3_2_1B_INST_Q4_0, loadModel } from "@qvac/sdk";
|
|
1
|
+
import { completion, LLAMA_3_2_1B_INST_Q4_0, loadModel, close, } from "@qvac/sdk";
|
|
2
2
|
// Topic hex (required)
|
|
3
3
|
const topicHex = process.argv[2];
|
|
4
4
|
if (!topicHex) {
|
|
@@ -48,7 +48,7 @@ try {
|
|
|
48
48
|
}
|
|
49
49
|
console.log("🔍 Stats:", await response.stats);
|
|
50
50
|
console.log("\n🎯 Delegation infrastructure working! Server correctly detected and routed the delegated request.");
|
|
51
|
-
|
|
51
|
+
void close();
|
|
52
52
|
}
|
|
53
53
|
catch (error) {
|
|
54
54
|
console.error("❌ Error:", error);
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { downloadAsset, setConfig, close, LLAMA_3_2_1B_INST_Q4_0, } from "@qvac/sdk";
|
|
2
|
+
// ⚠️ IMPORTANT: These are MOCK relay public keys for demonstration only
|
|
3
|
+
// To use blind relays in production:
|
|
4
|
+
// 1. Run your own relay servers using hyperswarm
|
|
5
|
+
// 2. Use well-known public relays from trusted sources
|
|
6
|
+
// 3. Never rely on example/mock keys for production use
|
|
7
|
+
const MOCK_RELAY_PUBLIC_KEYS = [
|
|
8
|
+
"0000000000000000000000000000000000000000000000000000000000000001",
|
|
9
|
+
"0000000000000000000000000000000000000000000000000000000000000002",
|
|
10
|
+
"0000000000000000000000000000000000000000000000000000000000000003",
|
|
11
|
+
];
|
|
12
|
+
console.log(`🚀 Download with Blind Relays Example`);
|
|
13
|
+
console.log(`${"=".repeat(60)}\n`);
|
|
14
|
+
console.log(`⚠️ Using MOCK relay keys - replace with real relays!\n`);
|
|
15
|
+
try {
|
|
16
|
+
// Configure SDK to use blind relays for improved connectivity
|
|
17
|
+
// Blind relays help with NAT traversal and firewall bypassing
|
|
18
|
+
await setConfig({
|
|
19
|
+
swarmRelays: MOCK_RELAY_PUBLIC_KEYS,
|
|
20
|
+
});
|
|
21
|
+
console.log(`✅ Configured ${MOCK_RELAY_PUBLIC_KEYS.length} blind relays`);
|
|
22
|
+
console.log(`📥 Starting model download from Hyperdrive...\n`);
|
|
23
|
+
const startTime = Date.now();
|
|
24
|
+
// Download model with progress tracking
|
|
25
|
+
await downloadAsset({
|
|
26
|
+
assetSrc: LLAMA_3_2_1B_INST_Q4_0,
|
|
27
|
+
onProgress: (progress) => {
|
|
28
|
+
const downloadedMB = (progress.downloaded / 1024 / 1024).toFixed(2);
|
|
29
|
+
const totalMB = (progress.total / 1024 / 1024).toFixed(2);
|
|
30
|
+
const percentage = progress.percentage.toFixed(1);
|
|
31
|
+
const elapsedSeconds = (Date.now() - startTime) / 1000;
|
|
32
|
+
const speedMBps = (progress.downloaded /
|
|
33
|
+
1024 /
|
|
34
|
+
1024 /
|
|
35
|
+
elapsedSeconds).toFixed(2);
|
|
36
|
+
console.log(`📊 ${percentage}% - ${downloadedMB}MB / ${totalMB}MB (${speedMBps} MB/s)`);
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
console.log(`\n✅ Model downloaded successfully using blind relays!`);
|
|
40
|
+
console.log(`Blind relays helped establish peer connections through NAT/firewalls\n`);
|
|
41
|
+
await close();
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
console.error("❌ Error:", error);
|
|
45
|
+
console.log(`\nIf download failed, ensure you're using valid relay public keys`);
|
|
46
|
+
console.log(` Mock keys in this example won't work in practice!`);
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { cancel, close, downloadAsset, LLAMA_3_2_1B_INST_Q4_0, } from "@qvac/sdk";
|
|
2
2
|
console.log(`🚀 Starting download with pause/resume example`);
|
|
3
3
|
console.log(`\n💡 Press Ctrl+C to pause the download (it will resume on restart)\n`);
|
|
4
4
|
let modelId;
|
|
@@ -31,13 +31,12 @@ try {
|
|
|
31
31
|
});
|
|
32
32
|
console.log(`\n✅ Model downloaded successfully! Model ID: ${modelId}`);
|
|
33
33
|
console.log("🎯 Download completed without interruption");
|
|
34
|
-
|
|
35
|
-
process.exit(0);
|
|
34
|
+
void close();
|
|
36
35
|
}
|
|
37
36
|
catch (error) {
|
|
38
37
|
if (error instanceof Error && error.message.includes("cancelled")) {
|
|
39
38
|
console.log("✅ Download was successfully cancelled");
|
|
40
|
-
|
|
39
|
+
void close();
|
|
41
40
|
}
|
|
42
41
|
else {
|
|
43
42
|
console.error("❌ Error:", error);
|
|
@@ -11,7 +11,6 @@ try {
|
|
|
11
11
|
console.log("Embedding (first 20 elements)", embedding.slice(0, 20));
|
|
12
12
|
console.log("Embeddings length", embedding.length);
|
|
13
13
|
await unloadModel({ modelId, clearStorage: false });
|
|
14
|
-
process.exit(0);
|
|
15
14
|
}
|
|
16
15
|
catch (error) {
|
|
17
16
|
console.error("❌ Error:", error);
|
|
@@ -80,7 +80,6 @@ try {
|
|
|
80
80
|
console.log(" - Privacy → Clear conversation history");
|
|
81
81
|
console.log(" - App reset → Delete all caches with { all: true }");
|
|
82
82
|
await unloadModel({ modelId, clearStorage: false });
|
|
83
|
-
process.exit(0);
|
|
84
83
|
}
|
|
85
84
|
catch (error) {
|
|
86
85
|
console.error("❌ Error:", error);
|
|
@@ -79,7 +79,6 @@ try {
|
|
|
79
79
|
console.log(" - Different cache keys provide complete isolation between sessions");
|
|
80
80
|
await deleteCache({ all: true });
|
|
81
81
|
await unloadModel({ modelId, clearStorage: false });
|
|
82
|
-
process.exit(0);
|
|
83
82
|
}
|
|
84
83
|
catch (error) {
|
|
85
84
|
console.error("❌ Error:", error);
|
|
@@ -66,7 +66,6 @@ try {
|
|
|
66
66
|
console.log(`\n⏱️ Non-cached completion stats: ${JSON.stringify(stats3)}\n`);
|
|
67
67
|
console.log("✅ KV Cache test completed!");
|
|
68
68
|
await unloadModel({ modelId, clearStorage: false });
|
|
69
|
-
process.exit(0);
|
|
70
69
|
}
|
|
71
70
|
catch (error) {
|
|
72
71
|
console.error("❌ Error:", error);
|
|
@@ -54,7 +54,6 @@ try {
|
|
|
54
54
|
// Show user where logs were saved
|
|
55
55
|
console.log(`\n📄 All logs (including model internals) saved to: ${logFile}`);
|
|
56
56
|
console.log("You can inspect the file to see detailed model operation logs!");
|
|
57
|
-
process.exit(0);
|
|
58
57
|
}
|
|
59
58
|
catch (error) {
|
|
60
59
|
console.error("❌ Error:", error);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { completion, loadModel } from "@qvac/sdk";
|
|
1
|
+
import { completion, loadModel, unloadModel } from "@qvac/sdk";
|
|
2
2
|
// Get GGUF file path from command line arguments
|
|
3
3
|
const ggufPath = process.argv[2];
|
|
4
4
|
if (!ggufPath) {
|
|
@@ -32,7 +32,7 @@ try {
|
|
|
32
32
|
const stats = await result.stats;
|
|
33
33
|
console.log("\n📊 Performance Stats:", stats);
|
|
34
34
|
console.log("\n\n🎉 Completed!");
|
|
35
|
-
|
|
35
|
+
await unloadModel({ modelId, clearStorage: false });
|
|
36
36
|
}
|
|
37
37
|
catch (error) {
|
|
38
38
|
console.error("❌ Error:", error);
|