@qvac/sdk 0.8.0 → 0.8.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/NOTICE +337 -0
- package/README.md +2 -2
- package/dist/client/api/cancel.d.ts +9 -0
- package/dist/client/api/cancel.js +9 -0
- package/dist/client/api/heartbeat.d.ts +30 -0
- package/dist/client/api/heartbeat.js +38 -0
- package/dist/client/api/index.d.ts +1 -1
- package/dist/client/api/index.js +1 -1
- package/dist/examples/embed-p2p.d.ts +2 -0
- package/dist/examples/llamacpp-p2p.d.ts +2 -0
- package/dist/examples/seed-p2p.d.ts +2 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/models/registry/models.d.ts +64 -64
- package/dist/models/registry/models.js +108 -108
- package/dist/schemas/cancel.d.ts +12 -0
- package/dist/schemas/cancel.js +2 -0
- package/dist/schemas/common.d.ts +39 -2
- package/dist/schemas/common.js +4 -3
- package/dist/schemas/delegate.d.ts +8 -0
- package/dist/schemas/delegate.js +5 -2
- package/dist/schemas/heartbeat.d.ts +17 -0
- package/dist/schemas/heartbeat.js +10 -0
- package/dist/schemas/index.d.ts +1 -1
- package/dist/schemas/index.js +1 -1
- package/dist/schemas/load-model.d.ts +113 -0
- package/dist/server/bare/delegate-rpc-client.js +42 -11
- package/dist/server/bare/plugins/nmtcpp-translation/plugin.js +1 -4
- package/dist/server/bare/registry/model-registry.d.ts +2 -0
- package/dist/server/bare/registry/model-registry.js +2 -1
- package/dist/server/rpc/delegate-transport.js +65 -44
- package/dist/server/rpc/delegate-utils.d.ts +2 -0
- package/dist/server/rpc/delegate-utils.js +5 -0
- package/dist/server/rpc/handler-registry.js +26 -3
- package/dist/server/rpc/handler-utils.js +43 -1
- package/dist/server/rpc/handlers/cancel-delegated.d.ts +4 -0
- package/dist/server/rpc/handlers/cancel-delegated.js +71 -0
- package/dist/server/rpc/handlers/completion-stream-delegated.js +2 -2
- package/dist/server/rpc/handlers/heartbeat-delegated.d.ts +4 -0
- package/dist/server/rpc/handlers/heartbeat-delegated.js +32 -0
- package/dist/server/rpc/handlers/heartbeat.d.ts +3 -0
- package/dist/server/rpc/handlers/heartbeat.js +3 -0
- package/dist/server/rpc/handlers/index.d.ts +2 -2
- package/dist/server/rpc/handlers/index.js +2 -2
- package/dist/server/rpc/handlers/load-model/registry.js +25 -41
- package/dist/server/rpc/handlers/load-model-delegated.js +6 -4
- package/dist/server/rpc/handlers/unload-model-delegated.js +3 -3
- package/package.json +10 -3
- package/dist/client/api/ping.d.ts +0 -11
- package/dist/client/api/ping.js +0 -19
- package/dist/examples/embed-hyperdrive.d.ts +0 -2
- package/dist/examples/llamacpp-hyperdrive.d.ts +0 -2
- package/dist/examples/seed-hyperdrive.d.ts +0 -2
- package/dist/schemas/ping.d.ts +0 -11
- package/dist/schemas/ping.js +0 -8
- package/dist/server/rpc/handlers/ping.d.ts +0 -3
- package/dist/server/rpc/handlers/ping.js +0 -3
- /package/dist/examples/{embed-hyperdrive.js → embed-p2p.js} +0 -0
- /package/dist/examples/{llamacpp-hyperdrive.js → llamacpp-p2p.js} +0 -0
- /package/dist/examples/{seed-hyperdrive.js → seed-p2p.js} +0 -0
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { promises as fsPromises } from "bare-fs";
|
|
2
2
|
import path from "bare-path";
|
|
3
|
-
import {} from "bare-stream";
|
|
4
3
|
import { AbortController } from "bare-abort-controller";
|
|
5
4
|
import { getModelsCacheDir, generateShortHash, detectShardedModel, getShardedModelCacheDir, getShardPath, getOnnxModelPath, measureChecksum, extractTensorsFromShards, calculatePercentage, } from "../../../utils/index.js";
|
|
6
5
|
import { getModelByPath } from "../../../../models/registry/index.js";
|
|
@@ -64,53 +63,38 @@ async function downloadSingleFileFromRegistry(registryPath, registrySource, mode
|
|
|
64
63
|
throw new DownloadCancelledError();
|
|
65
64
|
}
|
|
66
65
|
const client = await getRegistryClient();
|
|
67
|
-
let readStream;
|
|
68
|
-
if (blobBinding) {
|
|
69
|
-
logger.info(`📥 Downloading blob directly: ${modelFileName}`);
|
|
70
|
-
const result = await client.downloadBlob(blobBinding, {
|
|
71
|
-
timeout: REGISTRY_STREAM_TIMEOUT_MS,
|
|
72
|
-
});
|
|
73
|
-
if (!("stream" in result.artifact)) {
|
|
74
|
-
throw new RegistryDownloadFailedError(`No stream returned for blob ${modelFileName}`);
|
|
75
|
-
}
|
|
76
|
-
readStream = result.artifact.stream;
|
|
77
|
-
}
|
|
78
|
-
else {
|
|
79
|
-
logger.info(`📥 Downloading from registry: ${registryPath}`);
|
|
80
|
-
const result = await client.downloadModel(registryPath, registrySource, {
|
|
81
|
-
timeout: REGISTRY_STREAM_TIMEOUT_MS,
|
|
82
|
-
});
|
|
83
|
-
if (!("stream" in result.artifact)) {
|
|
84
|
-
throw new RegistryDownloadFailedError(`No stream returned for ${registryPath}`);
|
|
85
|
-
}
|
|
86
|
-
readStream = result.artifact.stream;
|
|
87
|
-
}
|
|
88
66
|
const dir = path.dirname(modelPath);
|
|
89
67
|
await fsPromises.mkdir(dir, { recursive: true });
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
if (progressCallback) {
|
|
68
|
+
// Adapt registry client's core.on("download") progress to SDK ModelProgressUpdate.
|
|
69
|
+
// This reports network-layer bytes, decoupled from disk I/O backpressure.
|
|
70
|
+
const onProgress = progressCallback
|
|
71
|
+
? (progress) => {
|
|
72
|
+
const total = progress.total || expectedSize || progress.downloaded;
|
|
96
73
|
progressCallback({
|
|
97
74
|
type: "modelProgress",
|
|
98
|
-
downloaded:
|
|
99
|
-
total
|
|
100
|
-
percentage:
|
|
101
|
-
? calculatePercentage(
|
|
75
|
+
downloaded: progress.downloaded,
|
|
76
|
+
total,
|
|
77
|
+
percentage: total > 0
|
|
78
|
+
? calculatePercentage(progress.downloaded, total)
|
|
102
79
|
: 0,
|
|
103
80
|
downloadKey,
|
|
104
81
|
});
|
|
105
82
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
83
|
+
: undefined;
|
|
84
|
+
const clientOptions = {
|
|
85
|
+
timeout: REGISTRY_STREAM_TIMEOUT_MS,
|
|
86
|
+
outputFile: modelPath,
|
|
87
|
+
...(onProgress && { onProgress }),
|
|
88
|
+
...(signal && { signal: signal }),
|
|
89
|
+
};
|
|
90
|
+
if (blobBinding) {
|
|
91
|
+
logger.info(`📥 Downloading blob directly: ${modelFileName}`);
|
|
92
|
+
await client.downloadBlob(blobBinding, clientOptions);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
logger.info(`📥 Downloading from registry: ${registryPath}`);
|
|
96
|
+
await client.downloadModel(registryPath, registrySource, clientOptions);
|
|
97
|
+
}
|
|
114
98
|
logger.info(`✅ Downloaded to ${modelPath}`);
|
|
115
99
|
const stats = await fsPromises.stat(modelPath);
|
|
116
100
|
if (expectedSize && stats.size !== expectedSize) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DELEGATION_BREAKDOWN_KEY, OPERATION_EVENT_KEY, modelInputToSrcSchema } from "../../../schemas/index.js";
|
|
2
2
|
import { registerModel, isModelLoaded, unregisterModel } from "../../bare/registry/model-registry.js";
|
|
3
3
|
import { send, stream, } from "../delegate-transport.js";
|
|
4
|
-
import { getRPC
|
|
4
|
+
import { getRPC } from "../../bare/delegate-rpc-client.js";
|
|
5
5
|
import { handleLoadModel } from "./load-model/index.js";
|
|
6
6
|
import { ModelLoadFailedError, DelegateNoFinalResponseError, } from "../../../utils/errors-server.js";
|
|
7
7
|
import { getServerLogger } from "../../../logging/index.js";
|
|
@@ -12,12 +12,13 @@ export async function handleLoadModelDelegated(request, options) {
|
|
|
12
12
|
throw new ModelLoadFailedError("Delegate information is required for delegated load model");
|
|
13
13
|
}
|
|
14
14
|
const { delegate } = request;
|
|
15
|
-
const { topic, providerPublicKey, timeout, fallbackToLocal, forceNewConnection, } = delegate;
|
|
15
|
+
const { topic, providerPublicKey, timeout, healthCheckTimeout, fallbackToLocal, forceNewConnection, } = delegate;
|
|
16
16
|
try {
|
|
17
17
|
logger.info(`📤 Sending delegated loadModel request to provider: ${providerPublicKey}${timeout ? `, timeout: ${timeout}ms` : ""}${forceNewConnection ? " (forcing new connection)" : ""}`);
|
|
18
18
|
// Create RPC instance for this HyperSwarm peer
|
|
19
19
|
const rpc = await getRPC(topic, providerPublicKey, {
|
|
20
20
|
timeout,
|
|
21
|
+
healthCheckTimeout,
|
|
21
22
|
forceNewConnection,
|
|
22
23
|
});
|
|
23
24
|
// Strip out the delegate field to avoid infinite delegation
|
|
@@ -82,6 +83,9 @@ export async function handleLoadModelDelegated(request, options) {
|
|
|
82
83
|
if (timeout !== undefined) {
|
|
83
84
|
delegateOptions.timeout = timeout;
|
|
84
85
|
}
|
|
86
|
+
if (healthCheckTimeout !== undefined) {
|
|
87
|
+
delegateOptions.healthCheckTimeout = healthCheckTimeout;
|
|
88
|
+
}
|
|
85
89
|
if (isModelLoaded(modelId)) {
|
|
86
90
|
logger.info(`Delegated model ${modelId} is already registered, replacing with new provider: ${providerPublicKey}`);
|
|
87
91
|
unregisterModel(modelId);
|
|
@@ -104,8 +108,6 @@ export async function handleLoadModelDelegated(request, options) {
|
|
|
104
108
|
}
|
|
105
109
|
catch (error) {
|
|
106
110
|
logger.error("Error in delegated load model:", error);
|
|
107
|
-
// Clean up stale RPC so next attempt creates a fresh connection
|
|
108
|
-
cleanupStaleConnection(providerPublicKey);
|
|
109
111
|
if (fallbackToLocal) {
|
|
110
112
|
logger.info("🔄 Fallback to local model loading enabled, attempting local load...");
|
|
111
113
|
try {
|
|
@@ -11,12 +11,12 @@ export async function handleUnloadModelDelegated(request) {
|
|
|
11
11
|
if (!entry?.isDelegated || !entry.delegated) {
|
|
12
12
|
throw new ModelIsDelegatedError(request.modelId);
|
|
13
13
|
}
|
|
14
|
-
const { topic, providerPublicKey, timeout } = entry.delegated;
|
|
14
|
+
const { topic, providerPublicKey, timeout, healthCheckTimeout } = entry.delegated;
|
|
15
15
|
unregisterModel(request.modelId);
|
|
16
16
|
try {
|
|
17
17
|
logger.info(`Sending delegated unload for model ${request.modelId} to provider: ${providerPublicKey}`);
|
|
18
|
-
const rpc = await getRPC(topic, providerPublicKey, { timeout });
|
|
19
|
-
await send({ type: "unloadModel", modelId: request.modelId, clearStorage: false }, rpc, { timeout });
|
|
18
|
+
const rpc = await getRPC(topic, providerPublicKey, { timeout, healthCheckTimeout });
|
|
19
|
+
await send({ type: "unloadModel", modelId: request.modelId, clearStorage: false }, rpc, { timeout, peerKey: providerPublicKey });
|
|
20
20
|
logger.info(`Delegated model ${request.modelId} unloaded on provider`);
|
|
21
21
|
}
|
|
22
22
|
catch (error) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qvac/sdk",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/tetherto/qvac.git",
|
|
8
|
+
"directory": "packages/sdk"
|
|
9
|
+
},
|
|
10
|
+
"bugs": "https://github.com/tetherto/qvac/issues",
|
|
11
|
+
"homepage": "https://github.com/tetherto/qvac/tree/main/packages/sdk#readme",
|
|
5
12
|
"type": "module",
|
|
6
13
|
"main": "./dist/index.js",
|
|
7
14
|
"types": "./dist/index.d.ts",
|
|
@@ -133,7 +140,7 @@
|
|
|
133
140
|
"@expo/config-plugins": "^54.0.1",
|
|
134
141
|
"@lancedb/lancedb": "^0.21.3",
|
|
135
142
|
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
136
|
-
"@qvac/cli": "^0.
|
|
143
|
+
"@qvac/cli": "^0.2.2",
|
|
137
144
|
"@sqliteai/sqlite-wasm": "3.50.4-sync.0.8.30-vector.0.9.23",
|
|
138
145
|
"@types/node": "^24.2.1",
|
|
139
146
|
"@types/tar-stream": "^3.1.4",
|
|
@@ -164,7 +171,7 @@
|
|
|
164
171
|
},
|
|
165
172
|
"peerDependencies": {
|
|
166
173
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
167
|
-
"@qvac/cli": "^0.
|
|
174
|
+
"@qvac/cli": "^0.2.2",
|
|
168
175
|
"bare-abort-controller": "^1.0.0",
|
|
169
176
|
"bare-buffer": "^3.4.2",
|
|
170
177
|
"bare-crypto": "^1.11.2",
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Sends a ping request to the server and returns the pong response.
|
|
3
|
-
*
|
|
4
|
-
* @returns A promise that resolves to a pong response containing a number.
|
|
5
|
-
* @throws {QvacErrorBase} When the response type is not "pong".
|
|
6
|
-
*/
|
|
7
|
-
export declare function ping(): Promise<{
|
|
8
|
-
type: "pong";
|
|
9
|
-
number: number;
|
|
10
|
-
}>;
|
|
11
|
-
//# sourceMappingURL=ping.d.ts.map
|
package/dist/client/api/ping.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import {} from "../../schemas/index.js";
|
|
2
|
-
import { send } from "../rpc/rpc-client.js";
|
|
3
|
-
import { InvalidResponseError } from "../../utils/errors-client.js";
|
|
4
|
-
/**
|
|
5
|
-
* Sends a ping request to the server and returns the pong response.
|
|
6
|
-
*
|
|
7
|
-
* @returns A promise that resolves to a pong response containing a number.
|
|
8
|
-
* @throws {QvacErrorBase} When the response type is not "pong".
|
|
9
|
-
*/
|
|
10
|
-
export async function ping() {
|
|
11
|
-
const request = {
|
|
12
|
-
type: "ping",
|
|
13
|
-
};
|
|
14
|
-
const response = await send(request);
|
|
15
|
-
if (response.type !== "pong") {
|
|
16
|
-
throw new InvalidResponseError("pong");
|
|
17
|
-
}
|
|
18
|
-
return response;
|
|
19
|
-
}
|
package/dist/schemas/ping.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
export declare const pingRequestSchema: z.ZodObject<{
|
|
3
|
-
type: z.ZodLiteral<"ping">;
|
|
4
|
-
}, z.core.$strip>;
|
|
5
|
-
export declare const pingResponseSchema: z.ZodObject<{
|
|
6
|
-
type: z.ZodLiteral<"pong">;
|
|
7
|
-
number: z.ZodNumber;
|
|
8
|
-
}, z.core.$strip>;
|
|
9
|
-
export type PingRequest = z.infer<typeof pingRequestSchema>;
|
|
10
|
-
export type PingResponse = z.infer<typeof pingResponseSchema>;
|
|
11
|
-
//# sourceMappingURL=ping.d.ts.map
|
package/dist/schemas/ping.js
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|