@qvac/sdk 0.13.4 → 0.14.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/NOTICE +95 -1151
- package/README.md +1 -2
- package/bare-imports.json +0 -5
- package/dist/client/api/bci-transcribe.js +2 -1
- package/dist/client/api/download-asset.js +2 -1
- package/dist/client/api/finetune.js +6 -5
- package/dist/client/api/index.d.ts +1 -0
- package/dist/client/api/index.js +1 -0
- package/dist/client/api/load-model.d.ts +11 -8
- package/dist/client/api/load-model.js +6 -6
- package/dist/client/api/subscribe-logs.d.ts +28 -0
- package/dist/client/api/subscribe-logs.js +43 -0
- package/dist/client/api/text-to-speech.js +2 -1
- package/dist/client/config-loader/config-utils.js +2 -4
- package/dist/client/config-loader/resolve-config.bare.js +4 -3
- package/dist/client/parse-input.d.ts +3 -0
- package/dist/client/parse-input.js +14 -0
- package/dist/client/rpc/node-rpc-client.js +8 -2
- package/dist/client/rpc/rpc-client.js +39 -7
- package/dist/commands/bundle/constants.js +2 -1
- package/dist/examples/bci/bci-filesystem-streaming.js +14 -14
- package/dist/examples/bci/bci-filesystem.js +17 -13
- package/dist/examples/cache-management.js +38 -38
- package/dist/examples/cancel-by-request-id.js +9 -9
- package/dist/examples/completion-events.js +20 -14
- package/dist/examples/completion-stop-reason.js +13 -7
- package/dist/examples/concurrent-completion-collision.js +7 -7
- package/dist/examples/config-reload.js +7 -8
- package/dist/examples/default-config-usage.js +4 -4
- package/dist/examples/delegated-inference/composite.js +14 -10
- package/dist/examples/delegated-inference/consumer-profiled.js +13 -13
- package/dist/examples/delegated-inference/consumer.js +16 -12
- package/dist/examples/delegated-inference/provider.js +12 -12
- package/dist/examples/diffusion-esrgan-upscale.js +19 -15
- package/dist/examples/diffusion-flux2-klein-img2img.js +16 -11
- package/dist/examples/diffusion-flux2-klein.js +14 -9
- package/dist/examples/diffusion-img2img.js +9 -10
- package/dist/examples/diffusion-img2vid.js +17 -12
- package/dist/examples/diffusion-simple.js +1 -1
- package/dist/examples/diffusion-txt2img.js +14 -9
- package/dist/examples/diffusion-txt2vid.js +15 -10
- package/dist/examples/download-with-blind-relays.js +16 -21
- package/dist/examples/download-with-cancel.js +15 -16
- package/dist/examples/embed-multi-gpu.js +3 -4
- package/dist/examples/embed-p2p.js +11 -7
- package/dist/examples/finetune/llamacpp-finetune.js +7 -7
- package/dist/examples/kv-cache-cleanup.js +35 -35
- package/dist/examples/kv-cache-custom-key.js +24 -24
- package/dist/examples/kv-cache-example.js +9 -9
- package/dist/examples/llamacpp-cache.js +18 -14
- package/dist/examples/llamacpp-dynamic-tools.js +15 -9
- package/dist/examples/llamacpp-filesystem.js +15 -9
- package/dist/examples/llamacpp-http.js +12 -10
- package/dist/examples/llamacpp-multi-gpu.js +4 -4
- package/dist/examples/llamacpp-multimodal.js +13 -9
- package/dist/examples/llamacpp-p2p.js +8 -4
- package/dist/examples/llamacpp-sharded.js +5 -5
- package/dist/examples/llamacpp-structured-output.js +15 -9
- package/dist/examples/logging-file-transport.js +3 -3
- package/dist/examples/logging-global.d.ts +2 -0
- package/dist/examples/logging-global.js +34 -0
- package/dist/examples/logging-streaming.js +7 -10
- package/dist/examples/mcp-websearch.js +24 -18
- package/dist/examples/multi-model-demo.js +17 -11
- package/dist/examples/ocr-fasttext.js +14 -16
- package/dist/examples/parallel-download.js +7 -7
- package/dist/examples/plugins.js +40 -28
- package/dist/examples/profiling/basic.js +16 -10
- package/dist/examples/profiling/per-call.js +17 -11
- package/dist/examples/quickstart.bare.d.ts +2 -0
- package/dist/examples/quickstart.bare.js +18 -0
- package/dist/examples/quickstart.js +10 -3
- package/dist/examples/rag/rag-chromadb.js +18 -14
- package/dist/examples/rag/rag-hyperdb/cancellation.js +17 -14
- package/dist/examples/rag/rag-hyperdb/ingest.js +14 -12
- package/dist/examples/rag/rag-hyperdb/pipeline.js +19 -17
- package/dist/examples/rag/rag-hyperdb/workspaces.js +31 -27
- package/dist/examples/rag/rag-lancedb.js +12 -8
- package/dist/examples/rag/rag-sqlite.js +11 -7
- package/dist/examples/registry-query.js +17 -17
- package/dist/examples/seed-p2p.js +10 -6
- package/dist/examples/suspend-resume.js +20 -16
- package/dist/examples/tools/llamacpp-native-tools.js +24 -18
- package/dist/examples/tools/llamacpp-tools-gemma4.js +14 -8
- package/dist/examples/tools/llamacpp-tools-harmony-multiturn.js +20 -14
- package/dist/examples/tools/llamacpp-tools-pythonic.js +14 -8
- package/dist/examples/tools/llamacpp-tools-qwen35.js +14 -8
- package/dist/examples/transcription/parakeet-ctc-filesystem.js +12 -9
- package/dist/examples/transcription/parakeet-microphone-record.js +15 -9
- package/dist/examples/transcription/parakeet-microphone-stream.js +15 -9
- package/dist/examples/transcription/parakeet-sortformer-streaming.js +12 -6
- package/dist/examples/transcription/parakeet-sortformer.js +3 -5
- package/dist/examples/transcription/parakeet-tdt-filesystem.js +13 -10
- package/dist/examples/transcription/whispercpp-filesystem-streaming.js +16 -17
- package/dist/examples/transcription/whispercpp-filesystem.js +14 -10
- package/dist/examples/transcription/whispercpp-microphone-conversation.js +10 -10
- package/dist/examples/transcription/whispercpp-microphone-record.js +6 -6
- package/dist/examples/transcription/whispercpp-prompt.js +14 -10
- package/dist/examples/translation/translation-bergamot-batch.js +11 -7
- package/dist/examples/translation/translation-bergamot-pivot.js +13 -9
- package/dist/examples/translation/translation-bergamot.js +8 -4
- package/dist/examples/translation/translation-indic.js +8 -4
- package/dist/examples/translation/translation-llm-afriquegemma.js +7 -3
- package/dist/examples/translation/translation-llm-context.js +8 -4
- package/dist/examples/translation/translation-llm.js +7 -3
- package/dist/examples/translation/translation-stream.js +4 -4
- package/dist/examples/tts/chatterbox.js +19 -11
- package/dist/examples/tts/llm-to-tts-streaming.js +27 -14
- package/dist/examples/tts/supertonic-multilingual.js +18 -14
- package/dist/examples/tts/supertonic.js +19 -15
- package/dist/examples/tts/utils.js +1 -1
- package/dist/examples/vla-pi05.js +18 -14
- package/dist/examples/vla-smolvla.js +18 -14
- package/dist/examples/voice-assistant/voice-assistant.js +12 -12
- package/dist/index.d.ts +3 -4
- package/dist/index.js +3 -4
- package/dist/logging/client-logger.js +2 -1
- package/dist/logging/index.d.ts +1 -1
- package/dist/logging/index.js +1 -1
- package/dist/logging/namespaces.d.ts +1 -0
- package/dist/logging/namespaces.js +2 -0
- package/dist/logging/server-logger.js +1 -4
- package/dist/logging/utils.js +6 -1
- package/dist/models/registry/index.d.ts +17 -0
- package/dist/models/registry/index.js +20 -1
- package/dist/models/registry/models.d.ts +1062 -38
- package/dist/models/registry/models.js +3546 -2490
- package/dist/pear/pre.js +2 -2
- package/dist/schemas/bci-config.d.ts +37 -0
- package/dist/schemas/bci-config.js +2 -0
- package/dist/schemas/bci.d.ts +2 -0
- package/dist/schemas/common.d.ts +171 -94
- package/dist/schemas/completion-stream.d.ts +6 -3
- package/dist/schemas/completion-stream.js +10 -2
- package/dist/schemas/download-asset.d.ts +5 -5
- package/dist/schemas/engine-addon-map.d.ts +1 -1
- package/dist/schemas/engine-addon-map.js +6 -3
- package/dist/schemas/error.js +6 -1
- package/dist/schemas/llamacpp-config.d.ts +27 -8
- package/dist/schemas/llamacpp-config.js +19 -2
- package/dist/schemas/load-model.d.ts +4170 -570
- package/dist/schemas/load-model.js +85 -26
- package/dist/schemas/logging-stream.js +7 -1
- package/dist/schemas/model-src-utils.d.ts +6 -6
- package/dist/schemas/model-types.d.ts +14 -15
- package/dist/schemas/model-types.js +10 -11
- package/dist/schemas/ocr.d.ts +10 -8
- package/dist/schemas/ocr.js +8 -6
- package/dist/schemas/plugin.d.ts +6 -5
- package/dist/schemas/plugin.js +4 -4
- package/dist/schemas/rag.d.ts +4 -4
- package/dist/schemas/registry.d.ts +8 -8
- package/dist/schemas/registry.js +1 -1
- package/dist/schemas/reload-config.d.ts +6 -6
- package/dist/schemas/sdcpp-config.d.ts +12 -12
- package/dist/schemas/sdk-config.d.ts +171 -117
- package/dist/schemas/sdk-config.js +5 -5
- package/dist/schemas/sdk-errors-client.d.ts +1 -0
- package/dist/schemas/sdk-errors-client.js +7 -2
- package/dist/schemas/text-to-speech.d.ts +157 -13
- package/dist/schemas/text-to-speech.js +70 -7
- package/dist/schemas/transcription-config.d.ts +5 -1
- package/dist/schemas/transcription-config.js +2 -0
- package/dist/schemas/transcription.d.ts +3 -0
- package/dist/schemas/transcription.js +2 -1
- package/dist/schemas/translate.d.ts +6 -6
- package/dist/schemas/translate.js +2 -3
- package/dist/schemas/translation-config.d.ts +20 -20
- package/dist/server/bare/hyperswarm.js +3 -3
- package/dist/server/bare/ops/transcribe.js +46 -15
- package/dist/server/bare/plugins/bci-whispercpp-transcription/args.d.ts +3 -0
- package/dist/server/bare/plugins/bci-whispercpp-transcription/args.js +13 -0
- package/dist/server/bare/plugins/bci-whispercpp-transcription/plugin.d.ts +41 -0
- package/dist/server/bare/plugins/bci-whispercpp-transcription/plugin.js +6 -11
- package/dist/server/bare/plugins/bci-whispercpp-transcription/resolve-config.d.ts +75 -0
- package/dist/server/bare/plugins/bci-whispercpp-transcription/resolve-config.js +11 -0
- package/dist/server/bare/plugins/{onnx-ocr → ggml-ocr}/plugin.d.ts +16 -10
- package/dist/server/bare/plugins/{onnx-ocr → ggml-ocr}/plugin.js +25 -18
- package/dist/server/bare/plugins/index.d.ts +1 -1
- package/dist/server/bare/plugins/index.js +1 -1
- package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stats.d.ts +10 -0
- package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stats.js +29 -0
- package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stream.js +4 -22
- package/dist/server/bare/plugins/llamacpp-completion/plugin.d.ts +15 -7
- package/dist/server/bare/plugins/nmtcpp-translation/plugin.d.ts +7 -7
- package/dist/server/bare/plugins/parakeet-transcription/plugin.d.ts +2 -0
- package/dist/server/bare/plugins/sdcpp-generation/plugin.d.ts +10 -10
- package/dist/server/bare/plugins/tts-ggml/plugin.d.ts +14 -8
- package/dist/server/bare/plugins/tts-ggml/plugin.js +12 -0
- package/dist/server/bare/plugins/whispercpp-transcription/plugin.d.ts +3 -1
- package/dist/server/bare/registry/logging-stream-registry.d.ts +4 -2
- package/dist/server/bare/registry/logging-stream-registry.js +12 -7
- package/dist/server/bare/registry/model-config-utils.js +2 -2
- package/dist/server/bare/registry/registry-client.js +1 -1
- package/dist/server/bare/runtime-lifecycle.d.ts +9 -0
- package/dist/server/bare/runtime-lifecycle.js +24 -0
- package/dist/server/bare/types/addon-responses.d.ts +1 -0
- package/dist/server/env.js +7 -10
- package/dist/server/plugins/registry.js +2 -4
- package/dist/server/rpc/handlers/load-model/handler.js +2 -4
- package/dist/server/rpc/handlers/load-model/http.js +253 -51
- package/dist/server/rpc/handlers/logging-stream.js +4 -2
- package/dist/server/rpc/handlers/plugin-invoke.js +5 -16
- package/dist/server/utils/completion-normalizer.js +13 -4
- package/dist/server/utils/worker-lock.js +5 -5
- package/dist/server/worker-core.d.ts +1 -1
- package/dist/server/worker-core.js +28 -18
- package/dist/utils/errors-client.d.ts +3 -0
- package/dist/utils/errors-client.js +5 -0
- package/dist/utils/errors-server.d.ts +2 -0
- package/dist/utils/errors-server.js +3 -0
- package/dist/utils/zod-error.d.ts +3 -0
- package/dist/utils/zod-error.js +4 -0
- package/package.json +21 -24
- package/dist/polyfills/bare-globals.d.ts +0 -2
- package/dist/polyfills/bare-globals.js +0 -4
- package/dist/polyfills/bare-globals.noop.d.ts +0 -2
- package/dist/polyfills/bare-globals.noop.js +0 -1
- /package/dist/server/bare/plugins/{onnx-ocr → ggml-ocr}/ops/ocr-stream.d.ts +0 -0
- /package/dist/server/bare/plugins/{onnx-ocr → ggml-ocr}/ops/ocr-stream.js +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { cancel, close, downloadAsset, LLAMA_3_2_1B_INST_Q4_0, } from "@qvac/sdk";
|
|
2
|
-
console.log(
|
|
3
|
-
console.log(`\n
|
|
2
|
+
console.log(`▸ Starting download with pause/resume example`);
|
|
3
|
+
console.log(`\n▸ Press Ctrl+C to pause the download (it will resume on restart)\n`);
|
|
4
4
|
let modelId;
|
|
5
5
|
let cancelled = false;
|
|
6
6
|
try {
|
|
@@ -10,16 +10,15 @@ try {
|
|
|
10
10
|
// synchronous `requestId` field so we can cancel before it settles.
|
|
11
11
|
const download = downloadAsset({
|
|
12
12
|
assetSrc: LLAMA_3_2_1B_INST_Q4_0,
|
|
13
|
-
onProgress: (
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
onProgress: (p) => {
|
|
14
|
+
const mb = (n) => (n / 1e6).toFixed(1);
|
|
15
|
+
const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`;
|
|
16
|
+
process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
|
|
17
|
+
if (p.percentage >= 100)
|
|
18
|
+
process.stderr.write("\n");
|
|
18
19
|
// Example: Stops at 10% (or use Ctrl+C for manual stop)
|
|
19
|
-
if (
|
|
20
|
-
console.log("\n
|
|
21
|
-
console.log(`📊 Progress: ${percentage}% (${downloadedMB}MB / ${totalMB}MB)`);
|
|
22
|
-
console.log(progress);
|
|
20
|
+
if (p.percentage >= 10 && !cancelled) {
|
|
21
|
+
console.log("\n▸ Auto-cancelling at 10% for demo purposes...");
|
|
23
22
|
cancelled = true;
|
|
24
23
|
void cancel({
|
|
25
24
|
requestId: download.requestId,
|
|
@@ -28,18 +27,18 @@ try {
|
|
|
28
27
|
}
|
|
29
28
|
},
|
|
30
29
|
});
|
|
31
|
-
await download;
|
|
32
|
-
console.log(`\n
|
|
33
|
-
console.log("
|
|
30
|
+
modelId = await download;
|
|
31
|
+
console.log(`\n▸ Model downloaded successfully! Model ID: ${modelId}`);
|
|
32
|
+
console.log("▸ Download completed without interruption");
|
|
34
33
|
void close();
|
|
35
34
|
}
|
|
36
35
|
catch (error) {
|
|
37
36
|
if (error instanceof Error && error.message.includes("cancelled")) {
|
|
38
|
-
console.log("
|
|
37
|
+
console.log("▸ Download was successfully cancelled");
|
|
39
38
|
void close();
|
|
40
39
|
}
|
|
41
40
|
else {
|
|
42
|
-
console.error("
|
|
41
|
+
console.error("✖", error);
|
|
43
42
|
process.exit(1);
|
|
44
43
|
}
|
|
45
44
|
}
|
|
@@ -30,16 +30,15 @@ try {
|
|
|
30
30
|
];
|
|
31
31
|
for (const text of texts) {
|
|
32
32
|
const { embedding, stats } = await embed({ modelId, text });
|
|
33
|
-
console.log(
|
|
34
|
-
console.log(` Dimensions: ${embedding.length}`);
|
|
33
|
+
console.log(`${embedding.length} dims ${text.slice(0, 50)}...`);
|
|
35
34
|
if (stats) {
|
|
36
|
-
console.log(
|
|
35
|
+
console.log(`▸ ${stats.backendDevice} ${stats.tokensPerSecond?.toFixed(1)} tok/s`);
|
|
37
36
|
}
|
|
38
37
|
}
|
|
39
38
|
await unloadModel({ modelId, clearStorage: false });
|
|
40
39
|
process.exit(0);
|
|
41
40
|
}
|
|
42
41
|
catch (error) {
|
|
43
|
-
console.error("
|
|
42
|
+
console.error("✖", error);
|
|
44
43
|
process.exit(1);
|
|
45
44
|
}
|
|
@@ -9,15 +9,19 @@ function cosineSimilarity(vecA, vecB) {
|
|
|
9
9
|
try {
|
|
10
10
|
const modelId = await loadModel({
|
|
11
11
|
modelSrc: GTE_LARGE_FP16,
|
|
12
|
-
onProgress: (
|
|
13
|
-
|
|
12
|
+
onProgress: (p) => {
|
|
13
|
+
const mb = (n) => (n / 1e6).toFixed(1);
|
|
14
|
+
const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`;
|
|
15
|
+
process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
|
|
16
|
+
if (p.percentage >= 100)
|
|
17
|
+
process.stderr.write("\n");
|
|
14
18
|
},
|
|
15
19
|
modelConfig: {
|
|
16
20
|
gpuLayers: 99,
|
|
17
21
|
device: "gpu",
|
|
18
22
|
},
|
|
19
23
|
});
|
|
20
|
-
console.log("\n
|
|
24
|
+
console.log("\n▸ Example 1: Single Text Embedding");
|
|
21
25
|
console.log("=".repeat(50));
|
|
22
26
|
const { embedding: singleEmbedding } = await embed({
|
|
23
27
|
modelId,
|
|
@@ -26,7 +30,7 @@ try {
|
|
|
26
30
|
console.log("Input: 'Hello, world!'");
|
|
27
31
|
console.log("Embedding dimensions:", singleEmbedding.length);
|
|
28
32
|
console.log("First 10 values:", singleEmbedding.slice(0, 10));
|
|
29
|
-
console.log("\n
|
|
33
|
+
console.log("\n▸ Example 2: Batch Text Embeddings");
|
|
30
34
|
console.log("=".repeat(50));
|
|
31
35
|
const texts = [
|
|
32
36
|
"The quick brown fox jumps over the lazy dog",
|
|
@@ -41,16 +45,16 @@ try {
|
|
|
41
45
|
throw new Error("Expected 3 embeddings");
|
|
42
46
|
}
|
|
43
47
|
console.log("Each embedding dimensions:", emb1.length);
|
|
44
|
-
console.log("\n
|
|
48
|
+
console.log("\n▸ Similarity Analysis");
|
|
45
49
|
console.log("=".repeat(50));
|
|
46
50
|
const similarity1 = cosineSimilarity(emb1, emb2);
|
|
47
51
|
const similarity2 = cosineSimilarity(emb1, emb3);
|
|
48
52
|
console.log("Similarity between texts 1 and 2 (similar meaning):", similarity1.toFixed(4));
|
|
49
53
|
console.log("Similarity between texts 1 and 3 (different topics):", similarity2.toFixed(4));
|
|
50
|
-
console.log("\n
|
|
54
|
+
console.log("\n▸ Higher values indicate more similar meanings");
|
|
51
55
|
await unloadModel({ modelId, clearStorage: false });
|
|
52
56
|
}
|
|
53
57
|
catch (error) {
|
|
54
|
-
console.error("
|
|
58
|
+
console.error("✖", error);
|
|
55
59
|
process.exit(1);
|
|
56
60
|
}
|
|
@@ -5,7 +5,7 @@ let exitCode = 0;
|
|
|
5
5
|
async function readProgress(handle, onTick) {
|
|
6
6
|
for await (const tick of handle.progressStream) {
|
|
7
7
|
const phase = tick.is_train ? "train" : "val";
|
|
8
|
-
console.log(
|
|
8
|
+
console.log(`▸ epoch=${tick.current_epoch + 1} step=${tick.global_steps} batch=${tick.current_batch}/${tick.total_batches} ${phase} loss=${tick.loss?.toFixed(4)} acc=${tick.accuracy?.toFixed(4)} eta=${Math.round(tick.eta_ms / 1000)}s`);
|
|
9
9
|
onTick(tick.global_steps);
|
|
10
10
|
}
|
|
11
11
|
}
|
|
@@ -17,7 +17,7 @@ try {
|
|
|
17
17
|
ctx_size: 512,
|
|
18
18
|
},
|
|
19
19
|
});
|
|
20
|
-
console.log(
|
|
20
|
+
console.log(`▸ Model loaded with ID: ${modelId}`);
|
|
21
21
|
const loadedModelId = modelId;
|
|
22
22
|
const finetuneParams = {
|
|
23
23
|
modelId: loadedModelId,
|
|
@@ -43,7 +43,7 @@ try {
|
|
|
43
43
|
const progressTask = readProgress(handle, (globalSteps) => {
|
|
44
44
|
if (pauseResumeEnabled && !pauseRequested && globalSteps >= 10) {
|
|
45
45
|
pauseRequested = true;
|
|
46
|
-
console.log("
|
|
46
|
+
console.log("▸ Requesting a pause so the run can be resumed...");
|
|
47
47
|
pauseResultPromise = finetune({
|
|
48
48
|
modelId: loadedModelId,
|
|
49
49
|
operation: "pause",
|
|
@@ -55,9 +55,9 @@ try {
|
|
|
55
55
|
if (pauseResultPromise) {
|
|
56
56
|
await pauseResultPromise;
|
|
57
57
|
}
|
|
58
|
-
console.log("
|
|
58
|
+
console.log("▸ Initial finetune result:", initialResult);
|
|
59
59
|
if (pauseResumeEnabled && initialResult.status === "PAUSED") {
|
|
60
|
-
console.log("
|
|
60
|
+
console.log("▸ Resuming from the saved checkpoint...");
|
|
61
61
|
const resumedHandle = finetune({
|
|
62
62
|
...finetuneParams,
|
|
63
63
|
operation: "resume",
|
|
@@ -65,11 +65,11 @@ try {
|
|
|
65
65
|
const resumedProgressTask = readProgress(resumedHandle, function () { });
|
|
66
66
|
const resumedResult = await resumedHandle.result;
|
|
67
67
|
await resumedProgressTask;
|
|
68
|
-
console.log("
|
|
68
|
+
console.log("▸ Resumed finetune result:", resumedResult);
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
catch (error) {
|
|
72
|
-
console.error("
|
|
72
|
+
console.error("✖", error);
|
|
73
73
|
exitCode = 1;
|
|
74
74
|
}
|
|
75
75
|
finally {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { completion, deleteCache, LLAMA_3_2_1B_INST_Q4_0, loadModel, unloadModel, VERBOSITY, } from "@qvac/sdk";
|
|
2
2
|
try {
|
|
3
|
-
console.log("
|
|
4
|
-
console.log("Cache structure: {kvCacheKey}/{modelId}/{configHash}.bin\n");
|
|
5
|
-
console.log("=".repeat(70) + "\n");
|
|
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
6
|
const modelId = await loadModel({
|
|
7
7
|
modelSrc: LLAMA_3_2_1B_INST_Q4_0,
|
|
8
8
|
modelConfig: {
|
|
@@ -14,7 +14,7 @@ try {
|
|
|
14
14
|
// Create some cached sessions
|
|
15
15
|
const cacheKey1 = "user-alice-session";
|
|
16
16
|
const cacheKey2 = "user-bob-session";
|
|
17
|
-
console.log(
|
|
17
|
+
console.log(`▸ Creating cache for key: "${cacheKey1}"`);
|
|
18
18
|
const result1 = completion({
|
|
19
19
|
modelId,
|
|
20
20
|
history: [{ role: "user", content: "Hello, I'm Alice!" }],
|
|
@@ -24,8 +24,8 @@ try {
|
|
|
24
24
|
for await (const token of result1.tokenStream) {
|
|
25
25
|
process.stdout.write(token);
|
|
26
26
|
}
|
|
27
|
-
console.log("\n
|
|
28
|
-
console.log(
|
|
27
|
+
console.log("\n▸ Cache created\n");
|
|
28
|
+
console.log(`▸ Creating cache for key: "${cacheKey2}"`);
|
|
29
29
|
const result2 = completion({
|
|
30
30
|
modelId,
|
|
31
31
|
history: [{ role: "user", content: "Hello, I'm Bob!" }],
|
|
@@ -35,52 +35,52 @@ try {
|
|
|
35
35
|
for await (const token of result2.tokenStream) {
|
|
36
36
|
process.stdout.write(token);
|
|
37
37
|
}
|
|
38
|
-
console.log("\n
|
|
38
|
+
console.log("\n▸ Cache created\n");
|
|
39
39
|
// Now cleanup specific cache key
|
|
40
|
-
console.log("=".repeat(70));
|
|
41
|
-
console.log(`\n
|
|
40
|
+
console.log("▸ " + "=".repeat(70));
|
|
41
|
+
console.log(`\n▸ Deleting cache key: "${cacheKey1}"`);
|
|
42
42
|
const deleteResult1 = await deleteCache({ kvCacheKey: cacheKey1 });
|
|
43
43
|
if (deleteResult1.success) {
|
|
44
|
-
console.log(
|
|
45
|
-
console.log(
|
|
44
|
+
console.log(`▸ Deleted all caches for key "${cacheKey1}"`);
|
|
45
|
+
console.log(`▸ (Removed: ${cacheKey1}/{modelId}/{configHash}.bin)`);
|
|
46
46
|
}
|
|
47
47
|
// Delete specific model within a cache key
|
|
48
|
-
console.log(`\n
|
|
48
|
+
console.log(`\n▸ Deleting specific model in cache key: "${cacheKey2}"`);
|
|
49
49
|
const deleteResult2 = await deleteCache({
|
|
50
50
|
kvCacheKey: cacheKey2,
|
|
51
51
|
modelId: modelId,
|
|
52
52
|
});
|
|
53
53
|
if (deleteResult2.success) {
|
|
54
|
-
console.log(
|
|
55
|
-
console.log(
|
|
54
|
+
console.log(`▸ Deleted model "${modelId}" from cache key "${cacheKey2}"`);
|
|
55
|
+
console.log(`▸ (Removed: ${cacheKey2}/${modelId}/)`);
|
|
56
56
|
}
|
|
57
57
|
// Try to delete non-existent cache key (should succeed silently)
|
|
58
|
-
console.log(`\n
|
|
58
|
+
console.log(`\n▸ Deleting non-existent cache key: "non-existent"`);
|
|
59
59
|
const deleteResult3 = await deleteCache({ kvCacheKey: "non-existent" });
|
|
60
60
|
if (deleteResult3.success) {
|
|
61
|
-
console.log("
|
|
61
|
+
console.log("▸ Delete succeeded (cache key didn't exist)");
|
|
62
62
|
}
|
|
63
|
-
console.log("\n" + "=".repeat(70));
|
|
64
|
-
console.log("\n
|
|
65
|
-
console.log("-".repeat(70));
|
|
66
|
-
console.log("\
|
|
67
|
-
console.log('
|
|
68
|
-
console.log("
|
|
69
|
-
console.log("\
|
|
70
|
-
console.log('
|
|
71
|
-
console.log("
|
|
72
|
-
console.log("\
|
|
73
|
-
console.log("
|
|
74
|
-
console.log("
|
|
75
|
-
console.log("\n
|
|
76
|
-
console.log("
|
|
77
|
-
console.log("
|
|
78
|
-
console.log("
|
|
79
|
-
console.log("
|
|
80
|
-
console.log("
|
|
63
|
+
console.log("\n▸ " + "=".repeat(70));
|
|
64
|
+
console.log("\n▸ CLEANUP OPTIONS:");
|
|
65
|
+
console.log("▸ " + "-".repeat(70));
|
|
66
|
+
console.log("\n▸ 1. Delete entire cache key (all models):");
|
|
67
|
+
console.log('▸ await deleteCache({ kvCacheKey: "my-session" })');
|
|
68
|
+
console.log("▸ └─ Removes: my-session/ (entire directory)");
|
|
69
|
+
console.log("\n▸ 2. Delete specific model within cache key:");
|
|
70
|
+
console.log('▸ await deleteCache({ kvCacheKey: "my-session", modelId: "model-abc" })');
|
|
71
|
+
console.log("▸ └─ Removes: my-session/model-abc/ (specific model directory)");
|
|
72
|
+
console.log("\n▸ 3. Delete ALL caches (entire cache folder):");
|
|
73
|
+
console.log("▸ await deleteCache({ all: true })");
|
|
74
|
+
console.log("▸ └─ Removes: ALL cache files from all sessions and models");
|
|
75
|
+
console.log("\n▸ Use Cases:");
|
|
76
|
+
console.log("▸ - User logout → Delete user's cache key");
|
|
77
|
+
console.log("▸ - Model updated → Delete old model caches");
|
|
78
|
+
console.log("▸ - Disk space cleanup → Delete old cache keys or all caches");
|
|
79
|
+
console.log("▸ - Privacy → Clear conversation history");
|
|
80
|
+
console.log("▸ - App reset → Delete all caches with { all: true }");
|
|
81
81
|
await unloadModel({ modelId, clearStorage: false });
|
|
82
82
|
}
|
|
83
83
|
catch (error) {
|
|
84
|
-
console.error("
|
|
84
|
+
console.error("✖", error);
|
|
85
85
|
process.exit(1);
|
|
86
86
|
}
|
|
@@ -7,7 +7,7 @@ const systemPromptMessage = {
|
|
|
7
7
|
`,
|
|
8
8
|
};
|
|
9
9
|
try {
|
|
10
|
-
console.log("
|
|
10
|
+
console.log("▸ Simple KV Cache Demo: Same vs Different Cache Keys\n");
|
|
11
11
|
const modelId = await loadModel({
|
|
12
12
|
modelSrc: LLAMA_3_2_1B_INST_Q4_0,
|
|
13
13
|
modelConfig: {
|
|
@@ -17,26 +17,26 @@ try {
|
|
|
17
17
|
},
|
|
18
18
|
});
|
|
19
19
|
// Prompt 1 with cache key "session-a" (first time - no cache exists)
|
|
20
|
-
console.log('
|
|
21
|
-
console.log(" Status: Creating NEW cache (first time)\n");
|
|
20
|
+
console.log('▸ Prompt 1: "What is 2+2?" with cache key "session-a"');
|
|
21
|
+
console.log("▸ Status: Creating NEW cache (first time)\n");
|
|
22
22
|
const result1 = completion({
|
|
23
23
|
modelId,
|
|
24
24
|
history: [systemPromptMessage, { role: "user", content: "What is 2+2?" }],
|
|
25
25
|
stream: true,
|
|
26
26
|
kvCache: "session-a",
|
|
27
27
|
});
|
|
28
|
-
console.log("
|
|
28
|
+
console.log("▸ Response: ");
|
|
29
29
|
let response1 = "";
|
|
30
30
|
for await (const token of result1.tokenStream) {
|
|
31
31
|
response1 += token;
|
|
32
32
|
process.stdout.write(token);
|
|
33
33
|
}
|
|
34
34
|
const stats1 = await result1.stats;
|
|
35
|
-
console.log(`\n
|
|
35
|
+
console.log(`\n▸ Stats: TTFT=${stats1?.timeToFirstToken}ms, CacheTokens=${stats1?.cacheTokens}\n`);
|
|
36
36
|
// Prompt 2 with SAME cache key "session-a" (cache exists - optimized!)
|
|
37
37
|
// This continues the conversation - asking about the previous answer
|
|
38
|
-
console.log('\n
|
|
39
|
-
console.log(" Status: REUSING existing cache (only last message sent, but context remembered!)\n");
|
|
38
|
+
console.log('\n▸ Prompt 2: "Now multiply that result by 3" with cache key "session-a" (SAME)');
|
|
39
|
+
console.log("▸ Status: REUSING existing cache (only last message sent, but context remembered!)\n");
|
|
40
40
|
const result2 = completion({
|
|
41
41
|
modelId,
|
|
42
42
|
history: [
|
|
@@ -48,53 +48,53 @@ try {
|
|
|
48
48
|
stream: true,
|
|
49
49
|
kvCache: "session-a", // Same cache key!
|
|
50
50
|
});
|
|
51
|
-
console.log("
|
|
51
|
+
console.log("▸ Response: ");
|
|
52
52
|
for await (const token of result2.tokenStream) {
|
|
53
53
|
process.stdout.write(token);
|
|
54
54
|
}
|
|
55
55
|
const stats2 = await result2.stats;
|
|
56
|
-
console.log(`\n
|
|
56
|
+
console.log(`\n▸ Stats: TTFT=${stats2?.timeToFirstToken}ms, CacheTokens=${stats2?.cacheTokens}\n`);
|
|
57
57
|
// Prompt 3 with DIFFERENT cache key "session-b" (new cache)
|
|
58
|
-
console.log('\n
|
|
59
|
-
console.log(" Status: Creating NEW cache (different key = isolated cache)\n");
|
|
58
|
+
console.log('\n▸ Prompt 3: "What is 10+10?" with cache key "session-b" (DIFFERENT)');
|
|
59
|
+
console.log("▸ Status: Creating NEW cache (different key = isolated cache)\n");
|
|
60
60
|
const result3 = completion({
|
|
61
61
|
modelId,
|
|
62
62
|
history: [systemPromptMessage, { role: "user", content: "What is 10+10?" }],
|
|
63
63
|
stream: true,
|
|
64
64
|
kvCache: "session-b", // Different cache key!
|
|
65
65
|
});
|
|
66
|
-
console.log("
|
|
66
|
+
console.log("▸ Response: ");
|
|
67
67
|
for await (const token of result3.tokenStream) {
|
|
68
68
|
process.stdout.write(token);
|
|
69
69
|
}
|
|
70
70
|
const stats3 = await result3.stats;
|
|
71
|
-
console.log(`\n
|
|
71
|
+
console.log(`\n▸ Stats: TTFT=${stats3?.timeToFirstToken}ms, CacheTokens=${stats3?.cacheTokens}\n`);
|
|
72
72
|
// Prompt 4: Go back to session-a to trigger flush of session-b
|
|
73
|
-
console.log('\n
|
|
74
|
-
console.log(" Status: This should trigger session-b to be flushed to disk\n");
|
|
73
|
+
console.log('\n▸ Prompt 4: "What is 5+5?" with cache key "session-a" (BACK TO FIRST)');
|
|
74
|
+
console.log("▸ Status: This should trigger session-b to be flushed to disk\n");
|
|
75
75
|
const result4 = completion({
|
|
76
76
|
modelId,
|
|
77
77
|
history: [systemPromptMessage, { role: "user", content: "What is 5+5?" }],
|
|
78
78
|
stream: true,
|
|
79
79
|
kvCache: "session-a", // Back to session-a!
|
|
80
80
|
});
|
|
81
|
-
console.log("
|
|
81
|
+
console.log("▸ Response: ");
|
|
82
82
|
for await (const token of result4.tokenStream) {
|
|
83
83
|
process.stdout.write(token);
|
|
84
84
|
}
|
|
85
85
|
const stats4 = await result4.stats;
|
|
86
|
-
console.log(`\n
|
|
86
|
+
console.log(`\n▸ Stats: TTFT=${stats4?.timeToFirstToken}ms, CacheTokens=${stats4?.cacheTokens}\n`);
|
|
87
87
|
// Summary
|
|
88
|
-
console.log("\n
|
|
89
|
-
console.log(' - Prompts 1 & 2 share cache key "session-a" → same cache file');
|
|
90
|
-
console.log(" - Prompt 2 built on Prompt 1's context (model remembered the answer!)");
|
|
91
|
-
console.log(" - Only the last message was sent, but full conversation context maintained");
|
|
92
|
-
console.log(' - Prompt 3 uses cache key "session-b" → separate cache file (isolated)');
|
|
93
|
-
console.log(" - Different cache keys provide complete isolation between sessions");
|
|
88
|
+
console.log("\n▸ Summary:");
|
|
89
|
+
console.log('▸ - Prompts 1 & 2 share cache key "session-a" → same cache file');
|
|
90
|
+
console.log("▸ - Prompt 2 built on Prompt 1's context (model remembered the answer!)");
|
|
91
|
+
console.log("▸ - Only the last message was sent, but full conversation context maintained");
|
|
92
|
+
console.log('▸ - Prompt 3 uses cache key "session-b" → separate cache file (isolated)');
|
|
93
|
+
console.log("▸ - Different cache keys provide complete isolation between sessions");
|
|
94
94
|
await deleteCache({ all: true });
|
|
95
95
|
await unloadModel({ modelId, clearStorage: false });
|
|
96
96
|
}
|
|
97
97
|
catch (error) {
|
|
98
|
-
console.error("
|
|
98
|
+
console.error("✖", error);
|
|
99
99
|
process.exit(1);
|
|
100
100
|
}
|
|
@@ -9,9 +9,9 @@ try {
|
|
|
9
9
|
verbosity: VERBOSITY.ERROR,
|
|
10
10
|
},
|
|
11
11
|
});
|
|
12
|
-
console.log("
|
|
12
|
+
console.log("▸ Testing KV Cache functionality...\n");
|
|
13
13
|
// First conversation with auto-keyed cache enabled
|
|
14
|
-
console.log("
|
|
14
|
+
console.log("▸ First conversation (building cache for the next turn):");
|
|
15
15
|
const history1 = [
|
|
16
16
|
{ role: "user", content: "What is the capital of France?" },
|
|
17
17
|
];
|
|
@@ -26,9 +26,9 @@ try {
|
|
|
26
26
|
}
|
|
27
27
|
const final1 = await result1.final;
|
|
28
28
|
const stats1 = final1.stats;
|
|
29
|
-
console.log(`\n
|
|
29
|
+
console.log(`\n▸ First completion stats: ${JSON.stringify(stats1)}\n`);
|
|
30
30
|
// Continue conversation (should reuse the completed first-turn cache).
|
|
31
|
-
console.log("
|
|
31
|
+
console.log("▸ Continuing conversation (reusing previous turn cache):");
|
|
32
32
|
const history2 = [
|
|
33
33
|
{ role: "user", content: "What is the capital of France?" },
|
|
34
34
|
{
|
|
@@ -51,9 +51,9 @@ try {
|
|
|
51
51
|
process.stdout.write(token);
|
|
52
52
|
}
|
|
53
53
|
const stats2 = await result2.stats;
|
|
54
|
-
console.log(`\n
|
|
54
|
+
console.log(`\n▸ Second completion stats: ${JSON.stringify(stats2)}\n`);
|
|
55
55
|
// Compare with non-cached version
|
|
56
|
-
console.log("
|
|
56
|
+
console.log("▸ Same conversation without cache:");
|
|
57
57
|
const result3 = completion({
|
|
58
58
|
modelId,
|
|
59
59
|
history: history2,
|
|
@@ -64,11 +64,11 @@ try {
|
|
|
64
64
|
process.stdout.write(token);
|
|
65
65
|
}
|
|
66
66
|
const stats3 = await result3.stats;
|
|
67
|
-
console.log(`\n
|
|
68
|
-
console.log("
|
|
67
|
+
console.log(`\n▸ Non-cached completion stats: ${JSON.stringify(stats3)}\n`);
|
|
68
|
+
console.log("▸ KV Cache test completed!");
|
|
69
69
|
await unloadModel({ modelId, clearStorage: false });
|
|
70
70
|
}
|
|
71
71
|
catch (error) {
|
|
72
|
-
console.error("
|
|
72
|
+
console.error("✖", error);
|
|
73
73
|
process.exit(1);
|
|
74
74
|
}
|
|
@@ -6,16 +6,16 @@ const systemPrompt = {
|
|
|
6
6
|
content: "You are a concise travel assistant. Keep track of the user's preferences across turns.",
|
|
7
7
|
};
|
|
8
8
|
function printStats(stats) {
|
|
9
|
-
console.log("\
|
|
9
|
+
console.log("\n▸ Performance Stats:", {
|
|
10
10
|
timeToFirstToken: stats?.timeToFirstToken,
|
|
11
11
|
tokensPerSecond: stats?.tokensPerSecond,
|
|
12
12
|
cacheTokens: stats?.cacheTokens,
|
|
13
13
|
});
|
|
14
14
|
}
|
|
15
15
|
async function runCachedCompletion(params) {
|
|
16
|
-
console.log(`\n
|
|
17
|
-
console.log(
|
|
18
|
-
console.log("AI Response:");
|
|
16
|
+
console.log(`\n▸ ${params.label}`);
|
|
17
|
+
console.log(`▸ Cache key: ${params.kvCache || "disabled"}`);
|
|
18
|
+
console.log("▸ AI Response:");
|
|
19
19
|
const result = completion({
|
|
20
20
|
modelId: params.modelId,
|
|
21
21
|
history: params.history,
|
|
@@ -33,18 +33,22 @@ async function runCachedCompletion(params) {
|
|
|
33
33
|
}
|
|
34
34
|
let modelId;
|
|
35
35
|
try {
|
|
36
|
-
console.log("Loading llama.cpp model with cache support...");
|
|
36
|
+
console.log("▸ Loading llama.cpp model with cache support...");
|
|
37
37
|
modelId = await loadModel({
|
|
38
38
|
modelSrc: LLAMA_3_2_1B_INST_Q4_0,
|
|
39
39
|
modelConfig: {
|
|
40
40
|
ctx_size: 4096,
|
|
41
41
|
verbosity: VERBOSITY.ERROR,
|
|
42
42
|
},
|
|
43
|
-
onProgress: (
|
|
44
|
-
|
|
43
|
+
onProgress: (p) => {
|
|
44
|
+
const mb = (n) => (n / 1e6).toFixed(1);
|
|
45
|
+
const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`;
|
|
46
|
+
process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
|
|
47
|
+
if (p.percentage >= 100)
|
|
48
|
+
process.stderr.write("\n");
|
|
45
49
|
},
|
|
46
50
|
});
|
|
47
|
-
console.log(
|
|
51
|
+
console.log(`▸ Model loaded successfully. Model ID: ${modelId}`);
|
|
48
52
|
await deleteCache({ kvCacheKey: sharedCacheKey });
|
|
49
53
|
await deleteCache({ kvCacheKey: isolatedCacheKey });
|
|
50
54
|
const firstUserMessage = {
|
|
@@ -83,10 +87,10 @@ try {
|
|
|
83
87
|
},
|
|
84
88
|
],
|
|
85
89
|
});
|
|
86
|
-
console.log("\
|
|
87
|
-
console.log(
|
|
88
|
-
console.log(
|
|
89
|
-
console.log('- Use deleteCache({ kvCacheKey: "your-session" }) to clear a saved session.');
|
|
90
|
+
console.log("\n▸ Summary:");
|
|
91
|
+
console.log(`▸ - Reusing "${sharedCacheKey}" keeps conversation context across turns.`);
|
|
92
|
+
console.log(`▸ - Switching to "${isolatedCacheKey}" starts a separate cache session.`);
|
|
93
|
+
console.log('▸ - Use deleteCache({ kvCacheKey: "your-session" }) to clear a saved session.');
|
|
90
94
|
await deleteCache({ kvCacheKey: sharedCacheKey });
|
|
91
95
|
await deleteCache({ kvCacheKey: isolatedCacheKey });
|
|
92
96
|
await unloadModel({ modelId, clearStorage: false });
|
|
@@ -98,9 +102,9 @@ catch (error) {
|
|
|
98
102
|
await unloadModel({ modelId, clearStorage: false });
|
|
99
103
|
}
|
|
100
104
|
catch (cleanupError) {
|
|
101
|
-
console.warn("
|
|
105
|
+
console.warn("✖ cleanup failed:", cleanupError);
|
|
102
106
|
}
|
|
103
107
|
}
|
|
104
|
-
console.error("
|
|
108
|
+
console.error("✖", error);
|
|
105
109
|
process.exit(1);
|
|
106
110
|
}
|
|
@@ -76,7 +76,7 @@ async function chatTurn({ modelId, kvCache, history, tools }) {
|
|
|
76
76
|
})();
|
|
77
77
|
const toolEventsTask = (async () => {
|
|
78
78
|
for await (const evt of result.toolCallStream) {
|
|
79
|
-
console.log(`\n
|
|
79
|
+
console.log(`\n▸ tool call: ${evt.call.name}(${JSON.stringify(evt.call.arguments)})`);
|
|
80
80
|
}
|
|
81
81
|
})();
|
|
82
82
|
await Promise.all([tokensTask, toolEventsTask]);
|
|
@@ -91,7 +91,7 @@ async function chatTurn({ modelId, kvCache, history, tools }) {
|
|
|
91
91
|
if (schema) {
|
|
92
92
|
const parsed = schema.safeParse(call.arguments);
|
|
93
93
|
if (!parsed.success) {
|
|
94
|
-
console.
|
|
94
|
+
console.log(`✖ validation failed for ${call.name}:`, parsed.error);
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
}
|
|
@@ -110,9 +110,15 @@ async function main() {
|
|
|
110
110
|
tools: true,
|
|
111
111
|
toolsMode: "dynamic",
|
|
112
112
|
},
|
|
113
|
-
onProgress: (
|
|
113
|
+
onProgress: (p) => {
|
|
114
|
+
const mb = (n) => (n / 1e6).toFixed(1);
|
|
115
|
+
const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`;
|
|
116
|
+
process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
|
|
117
|
+
if (p.percentage >= 100)
|
|
118
|
+
process.stderr.write("\n");
|
|
119
|
+
},
|
|
114
120
|
});
|
|
115
|
-
console.log(
|
|
121
|
+
console.log(`▸ Model loaded: ${modelId}`);
|
|
116
122
|
const kvCache = `dynamic-tools-${Date.now()}`;
|
|
117
123
|
const history = [
|
|
118
124
|
{
|
|
@@ -123,7 +129,7 @@ async function main() {
|
|
|
123
129
|
];
|
|
124
130
|
// Turn 1 — only weather tools available.
|
|
125
131
|
history.push({ role: "user", content: "What's the weather in Tokyo?" });
|
|
126
|
-
console.log("\n
|
|
132
|
+
console.log("\n▸ Turn 1 (tools=weather):\n");
|
|
127
133
|
await chatTurn({ modelId, kvCache, history, tools: weatherTools });
|
|
128
134
|
// Turn 2 — same session, swap to horoscope tools. Dynamic mode lets the
|
|
129
135
|
// model see a different tool set without invalidating the kv-cache.
|
|
@@ -131,16 +137,16 @@ async function main() {
|
|
|
131
137
|
role: "user",
|
|
132
138
|
content: "Now check my horoscope for Aquarius.",
|
|
133
139
|
});
|
|
134
|
-
console.log("\n\n
|
|
140
|
+
console.log("\n\n▸ Turn 2 (tools=horoscope):\n");
|
|
135
141
|
await chatTurn({ modelId, kvCache, history, tools: horoscopeTools });
|
|
136
142
|
// Turn 3 — swap to a parameterless tool to confirm empty-arg flows work.
|
|
137
143
|
history.push({ role: "user", content: "What's today's date?" });
|
|
138
|
-
console.log("\n\n
|
|
144
|
+
console.log("\n\n▸ Turn 3 (tools=date):\n");
|
|
139
145
|
await chatTurn({ modelId, kvCache, history, tools: dateTools });
|
|
140
|
-
console.log("\n\n
|
|
146
|
+
console.log("\n\n▸ Done.");
|
|
141
147
|
await unloadModel({ modelId, clearStorage: false });
|
|
142
148
|
}
|
|
143
149
|
main().catch((err) => {
|
|
144
|
-
console.error("
|
|
150
|
+
console.error("✖", err);
|
|
145
151
|
process.exit(1);
|
|
146
152
|
});
|