@qvac/sdk 0.1.1 → 0.2.0-dev.1760804157.f3c48d2
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 +3 -4
- package/dist/client/api/completion-stream.d.ts +19 -4
- package/dist/client/api/completion-stream.js +19 -4
- package/dist/client/api/delete-cache.d.ts +29 -0
- package/dist/client/api/delete-cache.js +47 -0
- package/dist/client/api/index.d.ts +1 -0
- package/dist/client/api/index.js +1 -0
- package/dist/client/rpc/bare-client.d.ts +5 -0
- package/dist/examples/kv-cache-cleanup.d.ts +2 -0
- package/dist/examples/kv-cache-cleanup.js +88 -0
- package/dist/examples/kv-cache-custom-key.d.ts +2 -0
- package/dist/examples/kv-cache-custom-key.js +87 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/schemas/common.d.ts +18 -6
- package/dist/schemas/common.js +3 -0
- package/dist/schemas/completion-stream.d.ts +5 -3
- package/dist/schemas/completion-stream.js +3 -2
- package/dist/schemas/delete-cache.d.ts +17 -0
- package/dist/schemas/delete-cache.js +17 -0
- package/dist/schemas/index.d.ts +1 -0
- package/dist/schemas/index.js +1 -0
- package/dist/schemas/llamacpp-config.d.ts +1 -1
- package/dist/schemas/llamacpp-config.js +1 -1
- package/dist/schemas/load-model.d.ts +6 -6
- package/dist/server/bare/addons/llamacpp/handlers/completion-stream.js +110 -54
- package/dist/server/bare/addons/llamacpp/kv-cache-utils.d.ts +13 -4
- package/dist/server/bare/addons/llamacpp/kv-cache-utils.js +70 -7
- package/dist/server/bare/addons/load-model.js +1 -1
- package/dist/server/bare/registry/model-registry.d.ts +7 -1
- package/dist/server/bare/registry/model-registry.js +9 -0
- package/dist/server/rpc/handle-request.js +11 -0
- package/dist/server/rpc/handlers/delete-cache.d.ts +3 -0
- package/dist/server/rpc/handlers/delete-cache.js +29 -0
- package/package.json +2 -2
- package/dist/models/hyperdrive/validation.d.ts +0 -6
- package/dist/models/hyperdrive/validation.js +0 -12
- package/dist/server/bare/utilities/audio/decoder.d.ts +0 -4
- package/dist/server/bare/utilities/audio/decoder.js +0 -38
- package/dist/server/bare/utilities/index.d.ts +0 -2
- package/dist/server/bare/utilities/index.js +0 -1
- package/dist/server/rpc/handlers/load-model/cache.d.ts +0 -2
- package/dist/server/rpc/handlers/load-model/cache.js +0 -15
package/README.md
CHANGED
|
@@ -79,7 +79,7 @@ npm i expo-file-system react-native-bare-kit
|
|
|
79
79
|
```js
|
|
80
80
|
export default {
|
|
81
81
|
expo: {
|
|
82
|
-
plugins: ["
|
|
82
|
+
plugins: ["qvac-sdk/expo-plugin"],
|
|
83
83
|
},
|
|
84
84
|
};
|
|
85
85
|
```
|
|
@@ -141,7 +141,6 @@ const cachedResponse = completion({
|
|
|
141
141
|
|
|
142
142
|
// Unload model to free up system resources
|
|
143
143
|
await unloadModel({ modelId });
|
|
144
|
-
process.exit();
|
|
145
144
|
```
|
|
146
145
|
|
|
147
146
|
**For more on how to use QVAC SDK, see [SDK at QVAC documentation](https://tether-2.gitbook.io/qvac-by-tether-or-reference/y2AsIh94H9DJ1pIBCNj9/sdk)**.
|
|
@@ -162,10 +161,10 @@ bun run build # or `watch` for hotreload
|
|
|
162
161
|
bun run build:pack
|
|
163
162
|
```
|
|
164
163
|
|
|
165
|
-
This outputs a tarball under `dist/qvac-sdk-{version}.tgz` that you can install in your project, e.g.:
|
|
164
|
+
This outputs a tarball under `dist/tetherto-qvac-sdk-{version}.tgz` that you can install in your project, e.g.:
|
|
166
165
|
|
|
167
166
|
```bash
|
|
168
|
-
npm i path/to/qvac-sdk-0.1.
|
|
167
|
+
npm i path/to/tetherto-qvac-sdk-0.0.1.tgz
|
|
169
168
|
```
|
|
170
169
|
|
|
171
170
|
## Examples
|
|
@@ -7,25 +7,40 @@ import { type CompletionStats, type CompletionClientParams } from "../../schemas
|
|
|
7
7
|
* @param params.history - Array of conversation messages with role, content, and optional attachments
|
|
8
8
|
* @param params.stream - Whether to stream tokens (true) or return complete response (false). Defaults to true
|
|
9
9
|
* @param params.tools - Optional array of tools that can be used by the model
|
|
10
|
-
* @param params.kvCache - Optional
|
|
10
|
+
* @param params.kvCache - Optional KV cache configuration. Cache files are organized hierarchically:
|
|
11
|
+
* - Structure: `{kvCacheKey}/{modelId}/{configHash}.bin`
|
|
12
|
+
* - The configHash includes model config + system prompt to ensure cache isolation
|
|
13
|
+
* - `true`: Auto-generate cache key based on conversation history
|
|
14
|
+
* - `"custom-key"`: Use provided string as cache key for manual session management
|
|
15
|
+
* - `false` or `undefined`: No caching
|
|
16
|
+
* - ⚡ Performance: When cache exists, only the last message is sent to the model (includes multimodal attachments)
|
|
17
|
+
* - 🗑️ Cleanup: Use `deleteCache({ kvCacheKey })` to remove cached sessions
|
|
11
18
|
* @returns Object with tokenStream generator, text promise, and stats promise
|
|
12
19
|
* @example
|
|
13
20
|
* ```typescript
|
|
14
|
-
* // Streaming mode
|
|
21
|
+
* // Streaming mode with auto-generated cache
|
|
15
22
|
* const result = completion({
|
|
16
23
|
* modelId: "llama-2",
|
|
17
24
|
* history: [
|
|
18
25
|
* { role: "user", content: "Hello, how are you?" }
|
|
19
26
|
* ],
|
|
20
27
|
* stream: true,
|
|
28
|
+
* kvCache: true, // Auto-generate cache key
|
|
21
29
|
* });
|
|
22
30
|
*
|
|
23
31
|
* for await (const token of result.tokenStream) {
|
|
24
32
|
* console.log(token);
|
|
25
33
|
* }
|
|
26
34
|
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
35
|
+
* // Custom session management with cache key
|
|
36
|
+
* const sessionResult = completion({
|
|
37
|
+
* modelId: "llama-2",
|
|
38
|
+
* history: [
|
|
39
|
+
* { role: "user", content: "Continue our conversation" }
|
|
40
|
+
* ],
|
|
41
|
+
* stream: true,
|
|
42
|
+
* kvCache: "user-session-123", // Custom cache key
|
|
43
|
+
* });
|
|
29
44
|
*
|
|
30
45
|
* // Non-streaming mode
|
|
31
46
|
* const response = completion({
|
|
@@ -8,25 +8,40 @@ import { stream as streamRpc } from "../rpc/rpc-client.js";
|
|
|
8
8
|
* @param params.history - Array of conversation messages with role, content, and optional attachments
|
|
9
9
|
* @param params.stream - Whether to stream tokens (true) or return complete response (false). Defaults to true
|
|
10
10
|
* @param params.tools - Optional array of tools that can be used by the model
|
|
11
|
-
* @param params.kvCache - Optional
|
|
11
|
+
* @param params.kvCache - Optional KV cache configuration. Cache files are organized hierarchically:
|
|
12
|
+
* - Structure: `{kvCacheKey}/{modelId}/{configHash}.bin`
|
|
13
|
+
* - The configHash includes model config + system prompt to ensure cache isolation
|
|
14
|
+
* - `true`: Auto-generate cache key based on conversation history
|
|
15
|
+
* - `"custom-key"`: Use provided string as cache key for manual session management
|
|
16
|
+
* - `false` or `undefined`: No caching
|
|
17
|
+
* - ⚡ Performance: When cache exists, only the last message is sent to the model (includes multimodal attachments)
|
|
18
|
+
* - 🗑️ Cleanup: Use `deleteCache({ kvCacheKey })` to remove cached sessions
|
|
12
19
|
* @returns Object with tokenStream generator, text promise, and stats promise
|
|
13
20
|
* @example
|
|
14
21
|
* ```typescript
|
|
15
|
-
* // Streaming mode
|
|
22
|
+
* // Streaming mode with auto-generated cache
|
|
16
23
|
* const result = completion({
|
|
17
24
|
* modelId: "llama-2",
|
|
18
25
|
* history: [
|
|
19
26
|
* { role: "user", content: "Hello, how are you?" }
|
|
20
27
|
* ],
|
|
21
28
|
* stream: true,
|
|
29
|
+
* kvCache: true, // Auto-generate cache key
|
|
22
30
|
* });
|
|
23
31
|
*
|
|
24
32
|
* for await (const token of result.tokenStream) {
|
|
25
33
|
* console.log(token);
|
|
26
34
|
* }
|
|
27
35
|
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
36
|
+
* // Custom session management with cache key
|
|
37
|
+
* const sessionResult = completion({
|
|
38
|
+
* modelId: "llama-2",
|
|
39
|
+
* history: [
|
|
40
|
+
* { role: "user", content: "Continue our conversation" }
|
|
41
|
+
* ],
|
|
42
|
+
* stream: true,
|
|
43
|
+
* kvCache: "user-session-123", // Custom cache key
|
|
44
|
+
* });
|
|
30
45
|
*
|
|
31
46
|
* // Non-streaming mode
|
|
32
47
|
* const response = completion({
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deletes KV cache files.
|
|
3
|
+
*
|
|
4
|
+
* @param params - The delete cache parameters
|
|
5
|
+
* @param params.all - If true, deletes all cache files
|
|
6
|
+
* @param params.kvCacheKey - The cache key to delete
|
|
7
|
+
* @param params.modelId - Optional: specific model ID to delete within the cache key. If not provided, deletes entire cache key.
|
|
8
|
+
* @returns Promise resolving to success status
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* // Delete all caches
|
|
12
|
+
* await deleteCache({ all: true });
|
|
13
|
+
*
|
|
14
|
+
* // Delete entire cache key (all models)
|
|
15
|
+
* await deleteCache({ kvCacheKey: "my-session" });
|
|
16
|
+
*
|
|
17
|
+
* // Delete only specific model within cache key
|
|
18
|
+
* await deleteCache({ kvCacheKey: "my-session", modelId: "model-abc123" });
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare function deleteCache(params: {
|
|
22
|
+
all: true;
|
|
23
|
+
} | {
|
|
24
|
+
kvCacheKey: string;
|
|
25
|
+
modelId?: string;
|
|
26
|
+
}): Promise<{
|
|
27
|
+
success: boolean;
|
|
28
|
+
}>;
|
|
29
|
+
//# sourceMappingURL=delete-cache.d.ts.map
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { send } from "../rpc/rpc-client.js";
|
|
2
|
+
/**
|
|
3
|
+
* Deletes KV cache files.
|
|
4
|
+
*
|
|
5
|
+
* @param params - The delete cache parameters
|
|
6
|
+
* @param params.all - If true, deletes all cache files
|
|
7
|
+
* @param params.kvCacheKey - The cache key to delete
|
|
8
|
+
* @param params.modelId - Optional: specific model ID to delete within the cache key. If not provided, deletes entire cache key.
|
|
9
|
+
* @returns Promise resolving to success status
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* // Delete all caches
|
|
13
|
+
* await deleteCache({ all: true });
|
|
14
|
+
*
|
|
15
|
+
* // Delete entire cache key (all models)
|
|
16
|
+
* await deleteCache({ kvCacheKey: "my-session" });
|
|
17
|
+
*
|
|
18
|
+
* // Delete only specific model within cache key
|
|
19
|
+
* await deleteCache({ kvCacheKey: "my-session", modelId: "model-abc123" });
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export async function deleteCache(params) {
|
|
23
|
+
let req;
|
|
24
|
+
if ("all" in params && params.all) {
|
|
25
|
+
req = {
|
|
26
|
+
type: "deleteCache",
|
|
27
|
+
all: true,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
else if ("kvCacheKey" in params) {
|
|
31
|
+
req = {
|
|
32
|
+
type: "deleteCache",
|
|
33
|
+
kvCacheKey: params.kvCacheKey,
|
|
34
|
+
modelId: params.modelId,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
throw new Error("Invalid deleteCache parameters");
|
|
39
|
+
}
|
|
40
|
+
const response = (await send(req));
|
|
41
|
+
if (!response.success && response.error) {
|
|
42
|
+
throw new Error(response.error);
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
success: response.success,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { loadModel } from "./load-model";
|
|
2
2
|
export { downloadAsset } from "./download-asset";
|
|
3
3
|
export { completion } from "./completion-stream";
|
|
4
|
+
export { deleteCache } from "./delete-cache";
|
|
4
5
|
export { unloadModel } from "./unload-model";
|
|
5
6
|
export { loggingStream } from "./logging-stream";
|
|
6
7
|
export { ping } from "./ping";
|
package/dist/client/api/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { loadModel } from "./load-model.js";
|
|
2
2
|
export { downloadAsset } from "./download-asset.js";
|
|
3
3
|
export { completion } from "./completion-stream.js";
|
|
4
|
+
export { deleteCache } from "./delete-cache.js";
|
|
4
5
|
export { unloadModel } from "./unload-model.js";
|
|
5
6
|
export { loggingStream } from "./logging-stream.js";
|
|
6
7
|
export { ping } from "./ping.js";
|
|
@@ -11,8 +11,13 @@ export declare function stream<T extends Request>(request: T): AsyncGenerator<{
|
|
|
11
11
|
stats?: {
|
|
12
12
|
timeToFirstToken: number;
|
|
13
13
|
tokensPerSecond: number;
|
|
14
|
+
cacheTokens: number;
|
|
14
15
|
} | undefined;
|
|
15
16
|
error?: string | undefined;
|
|
17
|
+
} | {
|
|
18
|
+
type: "deleteCache";
|
|
19
|
+
success: boolean;
|
|
20
|
+
error?: string | undefined;
|
|
16
21
|
} | {
|
|
17
22
|
type: "modelProgress";
|
|
18
23
|
downloaded: number;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { completion, deleteCache, LLAMA_3_2_1B_INST_Q4_0, loadModel, unloadModel, VERBOSITY, } from "@qvac/sdk";
|
|
2
|
+
try {
|
|
3
|
+
console.log("🧹 KV Cache Cleanup Demo\n");
|
|
4
|
+
console.log("Cache structure: {kvCacheKey}/{modelId}/{configHash}.bin\n");
|
|
5
|
+
console.log("=".repeat(70) + "\n");
|
|
6
|
+
const modelId = await loadModel({
|
|
7
|
+
modelSrc: LLAMA_3_2_1B_INST_Q4_0,
|
|
8
|
+
modelType: "llm",
|
|
9
|
+
modelConfig: {
|
|
10
|
+
device: "gpu",
|
|
11
|
+
ctx_size: 2048,
|
|
12
|
+
verbosity: VERBOSITY.SILENT,
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
// Create some cached sessions
|
|
16
|
+
const cacheKey1 = "user-alice-session";
|
|
17
|
+
const cacheKey2 = "user-bob-session";
|
|
18
|
+
console.log(`📝 Creating cache for key: "${cacheKey1}"`);
|
|
19
|
+
const result1 = completion({
|
|
20
|
+
modelId,
|
|
21
|
+
history: [{ role: "user", content: "Hello, I'm Alice!" }],
|
|
22
|
+
stream: true,
|
|
23
|
+
kvCache: cacheKey1,
|
|
24
|
+
});
|
|
25
|
+
for await (const token of result1.tokenStream) {
|
|
26
|
+
process.stdout.write(token);
|
|
27
|
+
}
|
|
28
|
+
console.log("\n✅ Cache created\n");
|
|
29
|
+
console.log(`📝 Creating cache for key: "${cacheKey2}"`);
|
|
30
|
+
const result2 = completion({
|
|
31
|
+
modelId,
|
|
32
|
+
history: [{ role: "user", content: "Hello, I'm Bob!" }],
|
|
33
|
+
stream: true,
|
|
34
|
+
kvCache: cacheKey2,
|
|
35
|
+
});
|
|
36
|
+
for await (const token of result2.tokenStream) {
|
|
37
|
+
process.stdout.write(token);
|
|
38
|
+
}
|
|
39
|
+
console.log("\n✅ Cache created\n");
|
|
40
|
+
// Now cleanup specific cache key
|
|
41
|
+
console.log("=".repeat(70));
|
|
42
|
+
console.log(`\n🗑️ Deleting cache key: "${cacheKey1}"`);
|
|
43
|
+
const deleteResult1 = await deleteCache({ kvCacheKey: cacheKey1 });
|
|
44
|
+
if (deleteResult1.success) {
|
|
45
|
+
console.log(`✅ Deleted all caches for key "${cacheKey1}"`);
|
|
46
|
+
console.log(` (Removed: ${cacheKey1}/{modelId}/{configHash}.bin)`);
|
|
47
|
+
}
|
|
48
|
+
// Delete specific model within a cache key
|
|
49
|
+
console.log(`\n🗑️ Deleting specific model in cache key: "${cacheKey2}"`);
|
|
50
|
+
const deleteResult2 = await deleteCache({
|
|
51
|
+
kvCacheKey: cacheKey2,
|
|
52
|
+
modelId: modelId,
|
|
53
|
+
});
|
|
54
|
+
if (deleteResult2.success) {
|
|
55
|
+
console.log(`✅ Deleted model "${modelId}" from cache key "${cacheKey2}"`);
|
|
56
|
+
console.log(` (Removed: ${cacheKey2}/${modelId}/)`);
|
|
57
|
+
}
|
|
58
|
+
// Try to delete non-existent cache key (should succeed silently)
|
|
59
|
+
console.log(`\n🗑️ Deleting non-existent cache key: "non-existent"`);
|
|
60
|
+
const deleteResult3 = await deleteCache({ kvCacheKey: "non-existent" });
|
|
61
|
+
if (deleteResult3.success) {
|
|
62
|
+
console.log("✅ Delete succeeded (cache key didn't exist)");
|
|
63
|
+
}
|
|
64
|
+
console.log("\n" + "=".repeat(70));
|
|
65
|
+
console.log("\n✅ CLEANUP OPTIONS:");
|
|
66
|
+
console.log("-".repeat(70));
|
|
67
|
+
console.log("\n1️⃣ Delete entire cache key (all models):");
|
|
68
|
+
console.log(' await deleteCache({ kvCacheKey: "my-session" })');
|
|
69
|
+
console.log(" └─ Removes: my-session/ (entire directory)");
|
|
70
|
+
console.log("\n2️⃣ Delete specific model within cache key:");
|
|
71
|
+
console.log(' await deleteCache({ kvCacheKey: "my-session", modelId: "model-abc" })');
|
|
72
|
+
console.log(" └─ Removes: my-session/model-abc/ (specific model directory)");
|
|
73
|
+
console.log("\n3️⃣ Delete ALL caches (entire cache folder):");
|
|
74
|
+
console.log(" await deleteCache({ all: true })");
|
|
75
|
+
console.log(" └─ Removes: ALL cache files from all sessions and models");
|
|
76
|
+
console.log("\n💡 Use Cases:");
|
|
77
|
+
console.log(" - User logout → Delete user's cache key");
|
|
78
|
+
console.log(" - Model updated → Delete old model caches");
|
|
79
|
+
console.log(" - Disk space cleanup → Delete old cache keys or all caches");
|
|
80
|
+
console.log(" - Privacy → Clear conversation history");
|
|
81
|
+
console.log(" - App reset → Delete all caches with { all: true }");
|
|
82
|
+
await unloadModel({ modelId, clearStorage: false });
|
|
83
|
+
process.exit(0);
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
console.error("❌ Error:", error);
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { completion, deleteCache, LLAMA_3_2_1B_INST_Q4_0, loadModel, unloadModel, VERBOSITY, } from "@qvac/sdk";
|
|
2
|
+
const systemPromptMessage = {
|
|
3
|
+
role: "system",
|
|
4
|
+
content: `You are a helpful mathematician assistant.
|
|
5
|
+
But because you are in the army you have to follow these rules:
|
|
6
|
+
- If anyone ask you to do an operation you have to answer with "Sir Yes Sir!" and then give the result
|
|
7
|
+
`,
|
|
8
|
+
};
|
|
9
|
+
try {
|
|
10
|
+
console.log("🧪 Simple KV Cache Demo: Same vs Different Cache Keys\n");
|
|
11
|
+
const modelId = await loadModel({
|
|
12
|
+
modelSrc: LLAMA_3_2_1B_INST_Q4_0,
|
|
13
|
+
modelType: "llm",
|
|
14
|
+
modelConfig: {
|
|
15
|
+
device: "gpu",
|
|
16
|
+
ctx_size: 2048,
|
|
17
|
+
verbosity: VERBOSITY.SILENT,
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
// Prompt 1 with cache key "session-a" (first time - no cache exists)
|
|
21
|
+
console.log('📝 Prompt 1: "What is 2+2?" with cache key "session-a"');
|
|
22
|
+
console.log(" Status: Creating NEW cache (first time)\n");
|
|
23
|
+
const result1 = completion({
|
|
24
|
+
modelId,
|
|
25
|
+
history: [systemPromptMessage, { role: "user", content: "What is 2+2?" }],
|
|
26
|
+
stream: true,
|
|
27
|
+
kvCache: "session-a",
|
|
28
|
+
});
|
|
29
|
+
console.log(" Response: ");
|
|
30
|
+
let response1 = "";
|
|
31
|
+
for await (const token of result1.tokenStream) {
|
|
32
|
+
response1 += token;
|
|
33
|
+
process.stdout.write(token);
|
|
34
|
+
}
|
|
35
|
+
const stats1 = await result1.stats;
|
|
36
|
+
console.log(`\n Stats: TTFT=${stats1?.timeToFirstToken}ms, CacheTokens=${stats1?.cacheTokens}\n`);
|
|
37
|
+
// Prompt 2 with SAME cache key "session-a" (cache exists - optimized!)
|
|
38
|
+
// This continues the conversation - asking about the previous answer
|
|
39
|
+
console.log('\n📝 Prompt 2: "Now multiply that result by 3" with cache key "session-a" (SAME)');
|
|
40
|
+
console.log(" Status: REUSING existing cache (only last message sent, but context remembered!)\n");
|
|
41
|
+
const result2 = completion({
|
|
42
|
+
modelId,
|
|
43
|
+
history: [
|
|
44
|
+
systemPromptMessage,
|
|
45
|
+
{ role: "user", content: "What is 2+2?" },
|
|
46
|
+
{ role: "assistant", content: response1 },
|
|
47
|
+
{ role: "user", content: "Now multiply that result by 3" }, // Refers to previous answer!
|
|
48
|
+
],
|
|
49
|
+
stream: true,
|
|
50
|
+
kvCache: "session-a", // Same cache key!
|
|
51
|
+
});
|
|
52
|
+
console.log(" Response: ");
|
|
53
|
+
for await (const token of result2.tokenStream) {
|
|
54
|
+
process.stdout.write(token);
|
|
55
|
+
}
|
|
56
|
+
const stats2 = await result2.stats;
|
|
57
|
+
console.log(`\n Stats: TTFT=${stats2?.timeToFirstToken}ms, CacheTokens=${stats2?.cacheTokens}\n`);
|
|
58
|
+
// Prompt 3 with DIFFERENT cache key "session-b" (new cache)
|
|
59
|
+
console.log('\n📝 Prompt 3: "What is 10+10?" with cache key "session-b" (DIFFERENT)');
|
|
60
|
+
console.log(" Status: Creating NEW cache (different key = isolated cache)\n");
|
|
61
|
+
const result3 = completion({
|
|
62
|
+
modelId,
|
|
63
|
+
history: [systemPromptMessage, { role: "user", content: "What is 10+10?" }],
|
|
64
|
+
stream: true,
|
|
65
|
+
kvCache: "session-b", // Different cache key!
|
|
66
|
+
});
|
|
67
|
+
console.log(" Response: ");
|
|
68
|
+
for await (const token of result3.tokenStream) {
|
|
69
|
+
process.stdout.write(token);
|
|
70
|
+
}
|
|
71
|
+
const stats3 = await result3.stats;
|
|
72
|
+
console.log(`\n Stats: TTFT=${stats3?.timeToFirstToken}ms, CacheTokens=${stats3?.cacheTokens}\n`);
|
|
73
|
+
// Summary
|
|
74
|
+
console.log("\n✅ Summary:");
|
|
75
|
+
console.log(' - Prompts 1 & 2 share cache key "session-a" → same cache file');
|
|
76
|
+
console.log(" - Prompt 2 built on Prompt 1's context (model remembered the answer!)");
|
|
77
|
+
console.log(" - Only the last message was sent, but full conversation context maintained");
|
|
78
|
+
console.log(' - Prompt 3 uses cache key "session-b" → separate cache file (isolated)');
|
|
79
|
+
console.log(" - Different cache keys provide complete isolation between sessions");
|
|
80
|
+
await deleteCache({ all: true });
|
|
81
|
+
await unloadModel({ modelId, clearStorage: false });
|
|
82
|
+
process.exit(0);
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
console.error("❌ Error:", error);
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { completion, loadModel, downloadAsset, ping, startQVACProvider, unloadModel, transcribe, transcribeStream, embed, translate, cancel, ragSaveEmbeddings, ragSearch, ragDeleteEmbeddings, } from "./client/api/index";
|
|
1
|
+
export { completion, deleteCache, loadModel, downloadAsset, ping, startQVACProvider, unloadModel, transcribe, transcribeStream, embed, translate, cancel, ragSaveEmbeddings, ragSearch, ragDeleteEmbeddings, } from "./client/api/index";
|
|
2
2
|
export { type ModelProgressUpdate, type LoadModelOptions, type DownloadAssetOptions, type Tool, VERBOSITY, type Attachment, type CompletionParams, type RagSearchResult, type RagSaveEmbeddingsResult, } from "./schemas/index";
|
|
3
3
|
export * from "./models/hyperdrive/index";
|
|
4
4
|
export { SUPPORTED_AUDIO_FORMATS } from "./constants/audio";
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Public API exports only
|
|
2
|
-
export { completion, loadModel, downloadAsset, ping, startQVACProvider, unloadModel, transcribe, transcribeStream, embed, translate, cancel, ragSaveEmbeddings, ragSearch, ragDeleteEmbeddings, } from "./client/api/index.js";
|
|
2
|
+
export { completion, deleteCache, loadModel, downloadAsset, ping, startQVACProvider, unloadModel, transcribe, transcribeStream, embed, translate, cancel, ragSaveEmbeddings, ragSearch, ragDeleteEmbeddings, } from "./client/api/index.js";
|
|
3
3
|
export { VERBOSITY, } from "./schemas/index.js";
|
|
4
4
|
// Hyperdrive model constants
|
|
5
5
|
export * from "./models/hyperdrive/index.js";
|
package/dist/schemas/common.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ export declare const requestSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
25
25
|
lora: z.ZodOptional<z.ZodString>;
|
|
26
26
|
device: z.ZodDefault<z.ZodString>;
|
|
27
27
|
predict: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<-1>, z.ZodLiteral<-2>, z.ZodNumber]>>;
|
|
28
|
-
system_prompt: z.
|
|
28
|
+
system_prompt: z.ZodDefault<z.ZodString>;
|
|
29
29
|
no_mmap: z.ZodOptional<z.ZodBoolean>;
|
|
30
30
|
verbosity: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<-1>, z.ZodLiteral<0>, z.ZodLiteral<1>]>>;
|
|
31
31
|
presence_penalty: z.ZodOptional<z.ZodNumber>;
|
|
@@ -186,13 +186,13 @@ export declare const requestSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
186
186
|
ctx_size: number;
|
|
187
187
|
gpu_layers: number;
|
|
188
188
|
device: string;
|
|
189
|
+
system_prompt: string;
|
|
189
190
|
temp?: number | undefined;
|
|
190
191
|
top_p?: number | undefined;
|
|
191
192
|
top_k?: number | undefined;
|
|
192
193
|
seed?: number | undefined;
|
|
193
194
|
lora?: string | undefined;
|
|
194
195
|
predict?: number | undefined;
|
|
195
|
-
system_prompt?: string | undefined;
|
|
196
196
|
no_mmap?: boolean | undefined;
|
|
197
197
|
verbosity?: 0 | 1 | -1 | undefined;
|
|
198
198
|
presence_penalty?: number | undefined;
|
|
@@ -283,13 +283,13 @@ export declare const requestSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
283
283
|
ctx_size: number;
|
|
284
284
|
gpu_layers: number;
|
|
285
285
|
device: string;
|
|
286
|
+
system_prompt: string;
|
|
286
287
|
temp?: number | undefined;
|
|
287
288
|
top_p?: number | undefined;
|
|
288
289
|
top_k?: number | undefined;
|
|
289
290
|
seed?: number | undefined;
|
|
290
291
|
lora?: string | undefined;
|
|
291
292
|
predict?: number | undefined;
|
|
292
|
-
system_prompt?: string | undefined;
|
|
293
293
|
no_mmap?: boolean | undefined;
|
|
294
294
|
verbosity?: 0 | 1 | -1 | undefined;
|
|
295
295
|
presence_penalty?: number | undefined;
|
|
@@ -419,7 +419,7 @@ export declare const requestSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
419
419
|
}, z.core.$strip>;
|
|
420
420
|
}, z.core.$strip>>>;
|
|
421
421
|
stream: z.ZodBoolean;
|
|
422
|
-
kvCache: z.ZodOptional<z.ZodBoolean
|
|
422
|
+
kvCache: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>;
|
|
423
423
|
type: z.ZodLiteral<"completionStream">;
|
|
424
424
|
}, z.core.$strip>, z.ZodObject<{
|
|
425
425
|
modelId: z.ZodString;
|
|
@@ -505,7 +505,14 @@ export declare const requestSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
505
505
|
ids: z.ZodArray<z.ZodString>;
|
|
506
506
|
type: z.ZodLiteral<"rag">;
|
|
507
507
|
operation: z.ZodLiteral<"deleteEmbeddings">;
|
|
508
|
-
}, z.core.$strip>], "operation"
|
|
508
|
+
}, z.core.$strip>], "operation">, z.ZodUnion<readonly [z.ZodObject<{
|
|
509
|
+
type: z.ZodLiteral<"deleteCache">;
|
|
510
|
+
all: z.ZodLiteral<true>;
|
|
511
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
512
|
+
type: z.ZodLiteral<"deleteCache">;
|
|
513
|
+
kvCacheKey: z.ZodString;
|
|
514
|
+
modelId: z.ZodOptional<z.ZodString>;
|
|
515
|
+
}, z.core.$strip>]>]>;
|
|
509
516
|
export declare const responseSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
510
517
|
type: z.ZodLiteral<"pong">;
|
|
511
518
|
number: z.ZodNumber;
|
|
@@ -526,6 +533,7 @@ export declare const responseSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
526
533
|
stats: z.ZodOptional<z.ZodObject<{
|
|
527
534
|
timeToFirstToken: z.ZodNumber;
|
|
528
535
|
tokensPerSecond: z.ZodNumber;
|
|
536
|
+
cacheTokens: z.ZodNumber;
|
|
529
537
|
}, z.core.$strip>>;
|
|
530
538
|
error: z.ZodOptional<z.ZodString>;
|
|
531
539
|
}, z.core.$strip>, z.ZodObject<{
|
|
@@ -616,7 +624,11 @@ export declare const responseSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
616
624
|
success: z.ZodBoolean;
|
|
617
625
|
error: z.ZodOptional<z.ZodString>;
|
|
618
626
|
operation: z.ZodLiteral<"deleteEmbeddings">;
|
|
619
|
-
}, z.core.$strip>], "operation"
|
|
627
|
+
}, z.core.$strip>], "operation">, z.ZodObject<{
|
|
628
|
+
type: z.ZodLiteral<"deleteCache">;
|
|
629
|
+
success: z.ZodBoolean;
|
|
630
|
+
error: z.ZodOptional<z.ZodString>;
|
|
631
|
+
}, z.core.$strip>], "type">;
|
|
620
632
|
export declare const rpcOptionsSchema: z.ZodObject<{
|
|
621
633
|
timeout: z.ZodOptional<z.ZodNumber>;
|
|
622
634
|
}, z.core.$strip>;
|
package/dist/schemas/common.js
CHANGED
|
@@ -12,6 +12,7 @@ import { translateRequestSchema, translateResponseSchema } from "./translate.js"
|
|
|
12
12
|
import { loggingStreamRequestSchema, loggingStreamResponseSchema, } from "./logging-stream.js";
|
|
13
13
|
import { errorResponseSchema } from "./error.js";
|
|
14
14
|
import { ragRequestSchema, ragResponseSchema } from "./rag.js";
|
|
15
|
+
import { deleteCacheRequestSchema, deleteCacheResponseSchema, } from "./delete-cache.js";
|
|
15
16
|
export const requestSchema = z.union([
|
|
16
17
|
pingRequestSchema,
|
|
17
18
|
loadModelRequestSchema,
|
|
@@ -25,6 +26,7 @@ export const requestSchema = z.union([
|
|
|
25
26
|
cancelRequestSchema,
|
|
26
27
|
provideRequestSchema,
|
|
27
28
|
ragRequestSchema,
|
|
29
|
+
deleteCacheRequestSchema,
|
|
28
30
|
]);
|
|
29
31
|
export const responseSchema = z.discriminatedUnion("type", [
|
|
30
32
|
pingResponseSchema,
|
|
@@ -41,6 +43,7 @@ export const responseSchema = z.discriminatedUnion("type", [
|
|
|
41
43
|
provideResponseSchema,
|
|
42
44
|
errorResponseSchema,
|
|
43
45
|
ragResponseSchema,
|
|
46
|
+
deleteCacheResponseSchema,
|
|
44
47
|
]);
|
|
45
48
|
export const rpcOptionsSchema = z.object({
|
|
46
49
|
timeout: z.number().min(100).optional(),
|
|
@@ -32,7 +32,7 @@ export declare const completionParamsSchema: z.ZodObject<{
|
|
|
32
32
|
}, z.core.$strip>>>;
|
|
33
33
|
}, z.core.$strip>>;
|
|
34
34
|
modelId: z.ZodString;
|
|
35
|
-
kvCache: z.ZodOptional<z.ZodBoolean
|
|
35
|
+
kvCache: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>;
|
|
36
36
|
}, z.core.$strip>;
|
|
37
37
|
export declare const completionClientParamsSchema: z.ZodObject<{
|
|
38
38
|
history: z.ZodArray<z.ZodObject<{
|
|
@@ -65,7 +65,7 @@ export declare const completionClientParamsSchema: z.ZodObject<{
|
|
|
65
65
|
}, z.core.$strip>;
|
|
66
66
|
}, z.core.$strip>>>;
|
|
67
67
|
stream: z.ZodBoolean;
|
|
68
|
-
kvCache: z.ZodOptional<z.ZodBoolean
|
|
68
|
+
kvCache: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>;
|
|
69
69
|
}, z.core.$strip>;
|
|
70
70
|
export declare const completionStreamRequestSchema: z.ZodObject<{
|
|
71
71
|
history: z.ZodArray<z.ZodObject<{
|
|
@@ -98,12 +98,13 @@ export declare const completionStreamRequestSchema: z.ZodObject<{
|
|
|
98
98
|
}, z.core.$strip>;
|
|
99
99
|
}, z.core.$strip>>>;
|
|
100
100
|
stream: z.ZodBoolean;
|
|
101
|
-
kvCache: z.ZodOptional<z.ZodBoolean
|
|
101
|
+
kvCache: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>;
|
|
102
102
|
type: z.ZodLiteral<"completionStream">;
|
|
103
103
|
}, z.core.$strip>;
|
|
104
104
|
export declare const completionStatsSchema: z.ZodObject<{
|
|
105
105
|
timeToFirstToken: z.ZodNumber;
|
|
106
106
|
tokensPerSecond: z.ZodNumber;
|
|
107
|
+
cacheTokens: z.ZodNumber;
|
|
107
108
|
}, z.core.$strip>;
|
|
108
109
|
export declare const completionStreamResponseSchema: z.ZodObject<{
|
|
109
110
|
type: z.ZodLiteral<"completionStream">;
|
|
@@ -112,6 +113,7 @@ export declare const completionStreamResponseSchema: z.ZodObject<{
|
|
|
112
113
|
stats: z.ZodOptional<z.ZodObject<{
|
|
113
114
|
timeToFirstToken: z.ZodNumber;
|
|
114
115
|
tokensPerSecond: z.ZodNumber;
|
|
116
|
+
cacheTokens: z.ZodNumber;
|
|
115
117
|
}, z.core.$strip>>;
|
|
116
118
|
error: z.ZodOptional<z.ZodString>;
|
|
117
119
|
}, z.core.$strip>;
|
|
@@ -30,12 +30,12 @@ export const completionParamsSchema = z.object({
|
|
|
30
30
|
attachments: z.array(attachmentSchema).optional(),
|
|
31
31
|
})),
|
|
32
32
|
modelId: z.string(),
|
|
33
|
-
kvCache: z.boolean().optional(),
|
|
33
|
+
kvCache: z.union([z.boolean(), z.string()]).optional(),
|
|
34
34
|
});
|
|
35
35
|
export const completionClientParamsSchema = completionParamsSchema.extend({
|
|
36
36
|
tools: z.array(toolSchema).optional(),
|
|
37
37
|
stream: z.boolean(),
|
|
38
|
-
kvCache: z.boolean().optional(),
|
|
38
|
+
kvCache: z.union([z.boolean(), z.string()]).optional(),
|
|
39
39
|
});
|
|
40
40
|
export const completionStreamRequestSchema = completionClientParamsSchema.extend({
|
|
41
41
|
type: z.literal("completionStream"),
|
|
@@ -43,6 +43,7 @@ export const completionStreamRequestSchema = completionClientParamsSchema.extend
|
|
|
43
43
|
export const completionStatsSchema = z.object({
|
|
44
44
|
timeToFirstToken: z.number(),
|
|
45
45
|
tokensPerSecond: z.number(),
|
|
46
|
+
cacheTokens: z.number(),
|
|
46
47
|
});
|
|
47
48
|
export const completionStreamResponseSchema = z.object({
|
|
48
49
|
type: z.literal("completionStream"),
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const deleteCacheRequestSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
3
|
+
type: z.ZodLiteral<"deleteCache">;
|
|
4
|
+
all: z.ZodLiteral<true>;
|
|
5
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
6
|
+
type: z.ZodLiteral<"deleteCache">;
|
|
7
|
+
kvCacheKey: z.ZodString;
|
|
8
|
+
modelId: z.ZodOptional<z.ZodString>;
|
|
9
|
+
}, z.core.$strip>]>;
|
|
10
|
+
export declare const deleteCacheResponseSchema: z.ZodObject<{
|
|
11
|
+
type: z.ZodLiteral<"deleteCache">;
|
|
12
|
+
success: z.ZodBoolean;
|
|
13
|
+
error: z.ZodOptional<z.ZodString>;
|
|
14
|
+
}, z.core.$strip>;
|
|
15
|
+
export type DeleteCacheRequest = z.infer<typeof deleteCacheRequestSchema>;
|
|
16
|
+
export type DeleteCacheResponse = z.infer<typeof deleteCacheResponseSchema>;
|
|
17
|
+
//# sourceMappingURL=delete-cache.d.ts.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const deleteCacheRequestSchema = z.union([
|
|
3
|
+
z.object({
|
|
4
|
+
type: z.literal("deleteCache"),
|
|
5
|
+
all: z.literal(true),
|
|
6
|
+
}),
|
|
7
|
+
z.object({
|
|
8
|
+
type: z.literal("deleteCache"),
|
|
9
|
+
kvCacheKey: z.string(),
|
|
10
|
+
modelId: z.string().optional(),
|
|
11
|
+
}),
|
|
12
|
+
]);
|
|
13
|
+
export const deleteCacheResponseSchema = z.object({
|
|
14
|
+
type: z.literal("deleteCache"),
|
|
15
|
+
success: z.boolean(),
|
|
16
|
+
error: z.string().optional(),
|
|
17
|
+
});
|
package/dist/schemas/index.d.ts
CHANGED
package/dist/schemas/index.js
CHANGED