@qvac/sdk 0.9.2 → 0.10.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 +42 -95
- package/dist/client/api/cancel.d.ts +1 -1
- package/dist/client/api/cancel.js +1 -1
- package/dist/client/api/completion-stream.d.ts +51 -12
- package/dist/client/api/completion-stream.js +129 -56
- package/dist/client/api/delete-cache.d.ts +1 -0
- package/dist/client/api/delete-cache.js +1 -0
- package/dist/client/api/diffusion.d.ts +17 -2
- package/dist/client/api/diffusion.js +21 -4
- package/dist/client/api/embed.d.ts +4 -0
- package/dist/client/api/finetune.d.ts +21 -0
- package/dist/client/api/get-loaded-model-info.d.ts +25 -0
- package/dist/client/api/get-loaded-model-info.js +36 -0
- package/dist/client/api/get-model-info.d.ts +9 -1
- package/dist/client/api/get-model-info.js +8 -0
- package/dist/client/api/heartbeat.d.ts +2 -2
- package/dist/client/api/heartbeat.js +2 -2
- package/dist/client/api/index.d.ts +3 -1
- package/dist/client/api/index.js +3 -1
- package/dist/client/api/invoke-plugin.d.ts +16 -0
- package/dist/client/api/invoke-plugin.js +16 -0
- package/dist/client/api/load-model.d.ts +36 -3
- package/dist/client/api/load-model.js +31 -10
- package/dist/client/api/provide.d.ts +11 -5
- package/dist/client/api/provide.js +11 -6
- package/dist/client/api/rag.d.ts +9 -0
- package/dist/client/api/rag.js +9 -0
- package/dist/client/api/registry.d.ts +26 -0
- package/dist/client/api/registry.js +26 -0
- package/dist/client/api/resume.d.ts +20 -4
- package/dist/client/api/resume.js +20 -4
- package/dist/client/api/state.d.ts +23 -0
- package/dist/client/api/state.js +29 -0
- package/dist/client/api/stop-provider.d.ts +11 -5
- package/dist/client/api/stop-provider.js +11 -5
- package/dist/client/api/suspend.d.ts +21 -3
- package/dist/client/api/suspend.js +21 -3
- package/dist/client/api/text-to-speech.d.ts +64 -6
- package/dist/client/api/text-to-speech.js +423 -47
- package/dist/client/api/transcribe.d.ts +29 -4
- package/dist/client/api/transcribe.js +86 -28
- package/dist/client/api/translate.d.ts +1 -0
- package/dist/client/api/translate.js +1 -0
- package/dist/client/rpc/bare-client.js +22 -1
- package/dist/client/rpc/expo-rpc-client.d.ts +1 -1
- package/dist/client/rpc/expo-rpc-client.js +96 -4
- package/dist/client/rpc/node-rpc-client.js +36 -0
- package/dist/examples/audio/mic-input.d.ts +9 -0
- package/dist/examples/audio/mic-input.js +111 -0
- package/dist/examples/completion-events.d.ts +18 -0
- package/dist/examples/completion-events.js +79 -0
- package/dist/examples/delegated-inference/composite.js +12 -18
- package/dist/examples/delegated-inference/consumer-profiled.js +4 -11
- package/dist/examples/delegated-inference/consumer.js +8 -13
- package/dist/examples/delegated-inference/provider.js +11 -16
- package/dist/examples/diffusion-flux2-klein-img2img.d.ts +2 -0
- package/dist/examples/diffusion-flux2-klein-img2img.js +60 -0
- package/dist/examples/diffusion-flux2-klein.js +1 -0
- package/dist/examples/diffusion-img2img.d.ts +2 -0
- package/dist/examples/diffusion-img2img.js +49 -0
- package/dist/examples/diffusion-txt2img.js +2 -1
- package/dist/examples/kv-cache-example.js +11 -12
- package/dist/examples/llamacpp-cache.d.ts +2 -0
- package/dist/examples/llamacpp-cache.js +107 -0
- package/dist/examples/llamacpp-dynamic-tools.d.ts +2 -0
- package/dist/examples/llamacpp-dynamic-tools.js +144 -0
- package/dist/examples/llamacpp-structured-output.d.ts +2 -0
- package/dist/examples/llamacpp-structured-output.js +106 -0
- package/dist/examples/plugins.js +4 -4
- package/dist/examples/suspend-resume.js +21 -4
- package/dist/examples/{llamacpp-native-tools.js → tools/llamacpp-native-tools.js} +6 -55
- package/dist/examples/tools/llamacpp-tools-harmony-multiturn.d.ts +2 -0
- package/dist/examples/tools/llamacpp-tools-harmony-multiturn.js +81 -0
- package/dist/examples/tools/llamacpp-tools-pythonic.d.ts +2 -0
- package/dist/examples/tools/llamacpp-tools-pythonic.js +50 -0
- package/dist/examples/tools/shared.d.ts +21 -0
- package/dist/examples/tools/shared.js +42 -0
- package/dist/examples/transcription/parakeet-microphone-record.js +6 -33
- package/dist/examples/transcription/whispercpp-filesystem-streaming.js +7 -5
- package/dist/examples/transcription/whispercpp-filesystem.js +12 -3
- package/dist/examples/transcription/whispercpp-microphone-record.js +6 -29
- package/dist/examples/translation/translation-stream.js +5 -5
- package/dist/examples/tts/llm-to-tts-streaming.d.ts +16 -0
- package/dist/examples/tts/llm-to-tts-streaming.js +143 -0
- package/dist/examples/tts/supertonic-multilingual.js +3 -3
- package/dist/examples/tts/supertonic.js +3 -3
- package/dist/examples/tts/utils.d.ts +11 -1
- package/dist/examples/tts/utils.js +70 -17
- package/dist/examples/voice-assistant/voice-assistant.d.ts +2 -0
- package/dist/examples/voice-assistant/voice-assistant.js +207 -0
- package/dist/expo/plugins/withMobileBundle.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/logging/logger.d.ts +11 -0
- package/dist/logging/logger.js +11 -0
- package/dist/logging/types.d.ts +18 -0
- package/dist/models/registry/models.d.ts +6973 -7457
- package/dist/models/registry/models.js +6889 -6855
- package/dist/models/update-models/codegen.js +84 -23
- package/dist/models/update-models/companions.d.ts +18 -0
- package/dist/models/update-models/companions.js +175 -0
- package/dist/models/update-models/naming.js +0 -25
- package/dist/models/update-models/registry.d.ts +1 -0
- package/dist/models/update-models/registry.js +23 -3
- package/dist/models/update-models/types.d.ts +37 -9
- package/dist/profiling/index.d.ts +49 -0
- package/dist/profiling/index.js +49 -0
- package/dist/schemas/cancel.d.ts +6 -2
- package/dist/schemas/cancel.js +14 -7
- package/dist/schemas/common.d.ts +354 -271
- package/dist/schemas/common.js +26 -5
- package/dist/schemas/completion-event.d.ts +225 -0
- package/dist/schemas/completion-event.js +79 -0
- package/dist/schemas/completion-stream.d.ts +126 -31
- package/dist/schemas/completion-stream.js +138 -36
- package/dist/schemas/delegate.d.ts +0 -2
- package/dist/schemas/delegate.js +25 -6
- package/dist/schemas/download-asset.d.ts +5 -5
- package/dist/schemas/embed.js +21 -9
- package/dist/schemas/engine-addon-map.d.ts +11 -1
- package/dist/schemas/engine-addon-map.js +2 -2
- package/dist/schemas/get-loaded-model-info.d.ts +52 -0
- package/dist/schemas/get-loaded-model-info.js +44 -0
- package/dist/schemas/get-model-info.d.ts +2 -2
- package/dist/schemas/get-model-info.js +103 -32
- package/dist/schemas/heartbeat.d.ts +0 -1
- package/dist/schemas/index.d.ts +4 -1
- package/dist/schemas/index.js +4 -1
- package/dist/schemas/llamacpp-config.d.ts +14 -4
- package/dist/schemas/llamacpp-config.js +5 -0
- package/dist/schemas/load-model.d.ts +3233 -1260
- package/dist/schemas/load-model.js +23 -16
- package/dist/schemas/model-src-utils.d.ts +7 -6
- package/dist/schemas/model-src-utils.js +27 -1
- package/dist/schemas/model-types.d.ts +4 -4
- package/dist/schemas/ocr.d.ts +1 -1
- package/dist/schemas/plugin.d.ts +27 -3
- package/dist/schemas/plugin.js +27 -2
- package/dist/schemas/profiling.js +11 -3
- package/dist/schemas/provide.d.ts +1 -3
- package/dist/schemas/provide.js +0 -3
- package/dist/schemas/rag.d.ts +4 -4
- package/dist/schemas/registry.d.ts +10 -10
- package/dist/schemas/registry.js +36 -14
- package/dist/schemas/reload-config.d.ts +73 -7
- package/dist/schemas/sdcpp-config.d.ts +16 -8
- package/dist/schemas/sdcpp-config.js +118 -25
- package/dist/schemas/sdk-config.d.ts +116 -90
- package/dist/schemas/sdk-config.js +16 -0
- package/dist/schemas/sdk-errors-client.d.ts +3 -0
- package/dist/schemas/sdk-errors-client.js +16 -1
- package/dist/schemas/sdk-errors-server.d.ts +3 -0
- package/dist/schemas/sdk-errors-server.js +23 -0
- package/dist/schemas/state.d.ts +23 -0
- package/dist/schemas/state.js +14 -0
- package/dist/schemas/stop-provide.d.ts +0 -5
- package/dist/schemas/stop-provide.js +2 -6
- package/dist/schemas/text-to-speech.d.ts +93 -27
- package/dist/schemas/text-to-speech.js +27 -0
- package/dist/schemas/tools.d.ts +16 -0
- package/dist/schemas/tools.js +15 -0
- package/dist/schemas/transcription-config.d.ts +8 -8
- package/dist/schemas/transcription.d.ts +33 -0
- package/dist/schemas/transcription.js +9 -0
- package/dist/schemas/translate.js +59 -19
- package/dist/schemas/translation-config.d.ts +157 -133
- package/dist/schemas/translation-config.js +34 -11
- package/dist/server/bare/delegate-rpc-client.d.ts +1 -1
- package/dist/server/bare/delegate-rpc-client.js +131 -122
- package/dist/server/bare/hyperswarm.d.ts +2 -2
- package/dist/server/bare/hyperswarm.js +12 -7
- package/dist/server/bare/ops/cancel.js +7 -0
- package/dist/server/bare/ops/kv-cache-utils.d.ts +7 -10
- package/dist/server/bare/ops/kv-cache-utils.js +31 -40
- package/dist/server/bare/ops/load-model.js +0 -1
- package/dist/server/bare/ops/transcribe.d.ts +11 -4
- package/dist/server/bare/ops/transcribe.js +25 -4
- package/dist/server/bare/ops/translate.js +42 -4
- package/dist/server/bare/ops/unload-model.js +21 -19
- package/dist/server/bare/plugins/llamacpp-completion/ops/cache-logger.js +1 -2
- package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stream.d.ts +13 -8
- package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stream.js +257 -85
- package/dist/server/bare/plugins/llamacpp-completion/ops/kv-cache-state.d.ts +101 -0
- package/dist/server/bare/plugins/llamacpp-completion/ops/kv-cache-state.js +135 -0
- package/dist/server/bare/plugins/llamacpp-completion/plugin.d.ts +80 -22
- package/dist/server/bare/plugins/llamacpp-completion/plugin.js +57 -32
- package/dist/server/bare/plugins/llamacpp-embedding/plugin.js +10 -16
- package/dist/server/bare/plugins/nmtcpp-translation/plugin.d.ts +69 -44
- package/dist/server/bare/plugins/nmtcpp-translation/plugin.js +54 -116
- package/dist/server/bare/plugins/nmtcpp-translation/resolve-vocab.d.ts +32 -0
- package/dist/server/bare/plugins/nmtcpp-translation/resolve-vocab.js +117 -0
- package/dist/server/bare/plugins/onnx-ocr/plugin.d.ts +1 -1
- package/dist/server/bare/plugins/onnx-ocr/plugin.js +1 -2
- package/dist/server/bare/plugins/onnx-tts/ops/text-to-speech-stream.d.ts +7 -0
- package/dist/server/bare/plugins/onnx-tts/ops/text-to-speech-stream.js +116 -0
- package/dist/server/bare/plugins/onnx-tts/ops/text-to-speech.d.ts +2 -3
- package/dist/server/bare/plugins/onnx-tts/ops/text-to-speech.js +71 -9
- package/dist/server/bare/plugins/onnx-tts/plugin.d.ts +41 -13
- package/dist/server/bare/plugins/onnx-tts/plugin.js +48 -3
- package/dist/server/bare/plugins/parakeet-transcription/plugin.d.ts +15 -7
- package/dist/server/bare/plugins/parakeet-transcription/plugin.js +5 -6
- package/dist/server/bare/plugins/sdcpp-generation/ops/diffusion.js +6 -0
- package/dist/server/bare/plugins/sdcpp-generation/plugin.d.ts +8 -5
- package/dist/server/bare/plugins/sdcpp-generation/plugin.js +13 -13
- package/dist/server/bare/plugins/whispercpp-transcription/plugin.d.ts +17 -1
- package/dist/server/bare/plugins/whispercpp-transcription/plugin.js +40 -17
- package/dist/server/bare/registry/config-registry.js +14 -3
- package/dist/server/bare/registry/model-registry.d.ts +8 -10
- package/dist/server/bare/registry/model-registry.js +17 -12
- package/dist/server/bare/registry/registry-client.js +79 -19
- package/dist/server/bare/runtime-lifecycle.d.ts +2 -1
- package/dist/server/bare/runtime-lifecycle.js +13 -2
- package/dist/server/bare/types/addon-responses.d.ts +8 -3
- package/dist/server/bare/utils/transcribe-metadata.d.ts +21 -0
- package/dist/server/bare/utils/transcribe-metadata.js +28 -0
- package/dist/server/bare/utils/tts-stats.d.ts +22 -0
- package/dist/server/bare/utils/tts-stats.js +10 -0
- package/dist/server/rpc/create-server.d.ts +4 -1
- package/dist/server/rpc/create-server.js +5 -1
- package/dist/server/rpc/delegate-transport.js +36 -29
- package/dist/server/rpc/handle-request.js +28 -3
- package/dist/server/rpc/handler-registry.js +7 -1
- package/dist/server/rpc/handler-utils.d.ts +5 -0
- package/dist/server/rpc/handler-utils.js +22 -0
- package/dist/server/rpc/handlers/cancel-delegated.js +3 -5
- package/dist/server/rpc/handlers/cancelHandler.js +4 -5
- package/dist/server/rpc/handlers/completion-stream-delegated.js +14 -5
- package/dist/server/rpc/handlers/delete-cache.js +8 -3
- package/dist/server/rpc/handlers/download-asset.js +3 -24
- package/dist/server/rpc/handlers/get-loaded-model-info.d.ts +3 -0
- package/dist/server/rpc/handlers/get-loaded-model-info.js +39 -0
- package/dist/server/rpc/handlers/get-model-info.js +93 -84
- package/dist/server/rpc/handlers/heartbeat-delegated.js +2 -2
- package/dist/server/rpc/handlers/index.d.ts +6 -0
- package/dist/server/rpc/handlers/index.js +6 -0
- package/dist/server/rpc/handlers/load-model/download-manager.d.ts +35 -9
- package/dist/server/rpc/handlers/load-model/download-manager.js +142 -38
- package/dist/server/rpc/handlers/load-model/download-stats.d.ts +5 -4
- package/dist/server/rpc/handlers/load-model/download-stats.js +49 -8
- package/dist/server/rpc/handlers/load-model/handler.js +31 -50
- package/dist/server/rpc/handlers/load-model/http.d.ts +2 -2
- package/dist/server/rpc/handlers/load-model/http.js +97 -142
- package/dist/server/rpc/handlers/load-model/hyperdrive.d.ts +2 -2
- package/dist/server/rpc/handlers/load-model/hyperdrive.js +55 -74
- package/dist/server/rpc/handlers/load-model/index.d.ts +0 -1
- package/dist/server/rpc/handlers/load-model/index.js +0 -1
- package/dist/server/rpc/handlers/load-model/registry-client-options.d.ts +27 -0
- package/dist/server/rpc/handlers/load-model/registry-client-options.js +19 -0
- package/dist/server/rpc/handlers/load-model/registry-companion-set.d.ts +22 -0
- package/dist/server/rpc/handlers/load-model/registry-companion-set.js +208 -0
- package/dist/server/rpc/handlers/load-model/registry-download-utils.d.ts +24 -0
- package/dist/server/rpc/handlers/load-model/registry-download-utils.js +114 -0
- package/dist/server/rpc/handlers/load-model/registry.d.ts +2 -20
- package/dist/server/rpc/handlers/load-model/registry.js +109 -381
- package/dist/server/rpc/handlers/load-model/resolve-session.d.ts +15 -0
- package/dist/server/rpc/handlers/load-model/resolve-session.js +61 -0
- package/dist/server/rpc/handlers/load-model/resolve.d.ts +3 -3
- package/dist/server/rpc/handlers/load-model/resolve.js +14 -23
- package/dist/server/rpc/handlers/load-model/types.d.ts +11 -4
- package/dist/server/rpc/handlers/load-model/types.js +28 -1
- package/dist/server/rpc/handlers/load-model-delegated.js +2 -4
- package/dist/server/rpc/handlers/plugin-dispatch.js +9 -5
- package/dist/server/rpc/handlers/plugin-invoke.js +1 -1
- package/dist/server/rpc/handlers/provideHandler/connection.js +13 -2
- package/dist/server/rpc/handlers/provideHandler/handler.js +42 -29
- package/dist/server/rpc/handlers/state.d.ts +3 -0
- package/dist/server/rpc/handlers/state.js +7 -0
- package/dist/server/rpc/handlers/stopProvideHandler.d.ts +2 -2
- package/dist/server/rpc/handlers/stopProvideHandler.js +12 -7
- package/dist/server/rpc/handlers/text-to-speech-stream.d.ts +3 -0
- package/dist/server/rpc/handlers/text-to-speech-stream.js +4 -0
- package/dist/server/rpc/handlers/unload-model-delegated.js +3 -3
- package/dist/server/rpc/profiling/operation-metrics.js +20 -0
- package/dist/server/rpc/rpc-utils.js +1 -1
- package/dist/server/rpc/transport-selector.d.ts +3 -0
- package/dist/server/rpc/transport-selector.js +18 -0
- package/dist/server/utils/cache/auto-history.d.ts +4 -0
- package/dist/server/utils/cache/auto-history.js +22 -0
- package/dist/server/utils/{cache.d.ts → cache/paths.d.ts} +22 -5
- package/dist/server/utils/{cache.js → cache/paths.js} +36 -20
- package/dist/server/utils/cache/types.d.ts +8 -0
- package/dist/server/utils/cache/types.js +1 -0
- package/dist/server/utils/checksum.d.ts +2 -2
- package/dist/server/utils/checksum.js +1 -1
- package/dist/server/utils/clear-storage.d.ts +5 -0
- package/dist/server/utils/clear-storage.js +17 -0
- package/dist/server/utils/completion-normalizer.d.ts +17 -0
- package/dist/server/utils/completion-normalizer.js +413 -0
- package/dist/server/utils/expand-gguf-shards.d.ts +3 -0
- package/dist/server/utils/expand-gguf-shards.js +22 -0
- package/dist/server/utils/formatting.js +1 -1
- package/dist/server/utils/index.d.ts +4 -2
- package/dist/server/utils/index.js +4 -2
- package/dist/server/utils/qvac-paths.d.ts +2 -0
- package/dist/server/utils/qvac-paths.js +5 -0
- package/dist/server/utils/response-format.d.ts +3 -0
- package/dist/server/utils/response-format.js +20 -0
- package/dist/server/utils/tool-integration.d.ts +15 -4
- package/dist/server/utils/tool-integration.js +21 -41
- package/dist/server/utils/tools/dialect.d.ts +8 -0
- package/dist/server/utils/tools/dialect.js +14 -0
- package/dist/server/utils/tools/index.d.ts +3 -0
- package/dist/server/utils/tools/index.js +2 -0
- package/dist/server/utils/tools/parser.d.ts +6 -0
- package/dist/server/utils/tools/parser.js +46 -0
- package/dist/server/utils/tools/parsers/harmony.d.ts +4 -0
- package/dist/server/utils/tools/parsers/harmony.js +59 -0
- package/dist/server/utils/tools/parsers/hermes.d.ts +4 -0
- package/dist/server/utils/tools/parsers/hermes.js +100 -0
- package/dist/server/utils/tools/parsers/json.d.ts +6 -0
- package/dist/server/utils/tools/parsers/json.js +115 -0
- package/dist/server/utils/tools/parsers/pythonic.d.ts +4 -0
- package/dist/server/utils/tools/parsers/pythonic.js +267 -0
- package/dist/server/utils/tools/shared.d.ts +18 -0
- package/dist/server/utils/tools/shared.js +54 -0
- package/dist/server/utils/worker-lock.d.ts +3 -0
- package/dist/server/utils/worker-lock.js +67 -0
- package/dist/server/worker-core.d.ts +16 -1
- package/dist/server/worker-core.js +114 -14
- package/dist/utils/aggregate-events.d.ts +16 -0
- package/dist/utils/aggregate-events.js +52 -0
- package/dist/utils/cache-normalize.d.ts +10 -0
- package/dist/utils/cache-normalize.js +23 -0
- package/dist/utils/encoding.d.ts +8 -0
- package/dist/utils/encoding.js +13 -0
- package/dist/utils/errors-client.d.ts +12 -0
- package/dist/utils/errors-client.js +20 -0
- package/dist/utils/errors-server.d.ts +14 -0
- package/dist/utils/errors-server.js +31 -0
- package/dist/utils/load-model-validation.d.ts +7 -0
- package/dist/utils/load-model-validation.js +18 -0
- package/expo/plugins/patches/android-link.mjs +1 -1
- package/expo/plugins/patches/ios-link.mjs +1 -1
- package/package.json +14 -18
- package/dist/examples/translation/translation-opus.d.ts +0 -2
- package/dist/examples/translation/translation-opus.js +0 -33
- package/dist/server/bare/utils/loader-adapter.d.ts +0 -7
- package/dist/server/bare/utils/loader-adapter.js +0 -9
- package/dist/server/utils/model-path.d.ts +0 -5
- package/dist/server/utils/model-path.js +0 -7
- package/dist/server/utils/tool-parser.d.ts +0 -7
- package/dist/server/utils/tool-parser.js +0 -248
- /package/dist/examples/{llamacpp-native-tools.d.ts → tools/llamacpp-native-tools.d.ts} +0 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event-driven completion — demonstrates the unified `CompletionEvent` stream.
|
|
3
|
+
*
|
|
4
|
+
* `completion()` returns a `CompletionRun` with two primary surfaces:
|
|
5
|
+
*
|
|
6
|
+
* - `events` — an `AsyncIterable<CompletionEvent>` of ordered, typed events
|
|
7
|
+
* (`contentDelta`, `thinkingDelta`, `toolCall`, `toolError`,
|
|
8
|
+
* `completionStats`, `completionDone`, `rawDelta`).
|
|
9
|
+
* - `final` — a `Promise<CompletionFinal>` that resolves once the stream
|
|
10
|
+
* ends, providing aggregated `contentText`, `thinkingText`,
|
|
11
|
+
* `toolCalls`, `stats`, and `raw.fullText`.
|
|
12
|
+
*
|
|
13
|
+
* Set `captureThinking: true` to attempt best-effort `<think>` block parsing
|
|
14
|
+
* into dedicated `thinkingDelta` events. `final.raw.fullText` keeps the exact
|
|
15
|
+
* model output.
|
|
16
|
+
*/
|
|
17
|
+
import { completion, loadModel, unloadModel, QWEN3_600M_INST_Q4, } from "@qvac/sdk";
|
|
18
|
+
try {
|
|
19
|
+
const modelId = await loadModel({
|
|
20
|
+
modelSrc: QWEN3_600M_INST_Q4,
|
|
21
|
+
modelType: "llm",
|
|
22
|
+
modelConfig: { ctx_size: 4096 },
|
|
23
|
+
onProgress: (p) => console.log(`Loading: ${p.percentage.toFixed(1)}%`),
|
|
24
|
+
});
|
|
25
|
+
console.log(`✅ Model loaded: ${modelId}\n`);
|
|
26
|
+
const result = completion({
|
|
27
|
+
modelId,
|
|
28
|
+
history: [{ role: "user", content: "Explain quantum computing in 2 sentences" }],
|
|
29
|
+
stream: true,
|
|
30
|
+
captureThinking: true,
|
|
31
|
+
});
|
|
32
|
+
for await (const event of result.events) {
|
|
33
|
+
handleEvent(event);
|
|
34
|
+
}
|
|
35
|
+
const final = await result.final;
|
|
36
|
+
console.log("\n\n--- Final Result ---");
|
|
37
|
+
console.log(`Content: ${final.contentText}\n`);
|
|
38
|
+
if (final.thinkingText) {
|
|
39
|
+
console.log(`Thinking: ${final.thinkingText}\n`);
|
|
40
|
+
}
|
|
41
|
+
if (final.stats) {
|
|
42
|
+
console.log(`Stats: ${final.stats.tokensPerSecond?.toFixed(1)} tok/s`);
|
|
43
|
+
}
|
|
44
|
+
if (final.toolCalls.length > 0) {
|
|
45
|
+
console.log(`Tool calls: ${final.toolCalls.map((c) => c.name).join(", ")}`);
|
|
46
|
+
}
|
|
47
|
+
console.log(`Raw output length: ${final.raw.fullText.length} chars`);
|
|
48
|
+
await unloadModel({ modelId, clearStorage: false });
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
console.error("❌ Error:", error);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
function handleEvent(event) {
|
|
55
|
+
switch (event.type) {
|
|
56
|
+
case "contentDelta":
|
|
57
|
+
process.stdout.write(event.text);
|
|
58
|
+
break;
|
|
59
|
+
case "thinkingDelta":
|
|
60
|
+
process.stdout.write(`\x1b[2m${event.text}\x1b[0m`);
|
|
61
|
+
break;
|
|
62
|
+
case "toolCall":
|
|
63
|
+
console.log(`\n→ Tool: ${event.call.name}(${JSON.stringify(event.call.arguments)})`);
|
|
64
|
+
break;
|
|
65
|
+
case "toolError":
|
|
66
|
+
console.warn(`\n⚠ Tool error [${event.error.code}]: ${event.error.message}`);
|
|
67
|
+
break;
|
|
68
|
+
case "completionStats":
|
|
69
|
+
console.log(`\n📊 ${event.stats.tokensPerSecond?.toFixed(1)} tok/s`);
|
|
70
|
+
break;
|
|
71
|
+
case "completionDone":
|
|
72
|
+
if (event.stopReason === "error" && "error" in event) {
|
|
73
|
+
console.error(`\n❌ ${event.error.message}`);
|
|
74
|
+
}
|
|
75
|
+
break;
|
|
76
|
+
case "rawDelta":
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -2,16 +2,14 @@ import { spawn } from "child_process";
|
|
|
2
2
|
import { join, dirname } from "path";
|
|
3
3
|
import { fileURLToPath } from "url";
|
|
4
4
|
import { completion, loadModel, close, LLAMA_3_2_1B_INST_Q4_0, } from "@qvac/sdk";
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
const
|
|
9
|
-
const PROVIDER_STARTUP_TIMEOUT_MS = 30_000;
|
|
5
|
+
// The consumer connects to the provider directly via its public key over the
|
|
6
|
+
// DHT (`dht.connect(publicKey)`). No topic or discovery step is involved —
|
|
7
|
+
// the provider just needs its DHT server listening on its keyPair.
|
|
8
|
+
const PROVIDER_STARTUP_TIMEOUT_MS = 60_000;
|
|
10
9
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
11
10
|
const providerScript = join(__dirname, "provider.ts");
|
|
12
|
-
// ── Provider lifecycle ──────────────────────────────────────────────
|
|
13
11
|
function spawnProviderProcess() {
|
|
14
|
-
const child = spawn("bun", ["run", providerScript
|
|
12
|
+
const child = spawn("bun", ["run", providerScript], {
|
|
15
13
|
stdio: ["pipe", "pipe", "pipe"],
|
|
16
14
|
});
|
|
17
15
|
child.stderr?.on("data", (chunk) => {
|
|
@@ -25,9 +23,9 @@ function terminateProvider(provider) {
|
|
|
25
23
|
}
|
|
26
24
|
}
|
|
27
25
|
// The provider's Hyperswarm identity (and therefore its public key) is
|
|
28
|
-
// generated at startup — it can't be known ahead of time. We parse it
|
|
29
|
-
//
|
|
30
|
-
// "🆔 Provider Public Key
|
|
26
|
+
// generated at startup — it can't be known ahead of time. We parse it from
|
|
27
|
+
// the provider's stdout where it prints:
|
|
28
|
+
// "🆔 Provider Public Key: <hex>"
|
|
31
29
|
function waitForProviderPublicKey(provider) {
|
|
32
30
|
return new Promise((resolve, reject) => {
|
|
33
31
|
let output = "";
|
|
@@ -38,7 +36,7 @@ function waitForProviderPublicKey(provider) {
|
|
|
38
36
|
const str = chunk.toString();
|
|
39
37
|
output += str;
|
|
40
38
|
process.stdout.write(str);
|
|
41
|
-
const match = output.match(/Provider Public Key
|
|
39
|
+
const match = output.match(/Provider Public Key: ([a-f0-9]+)/i);
|
|
42
40
|
if (match) {
|
|
43
41
|
clearTimeout(timeout);
|
|
44
42
|
resolve(match[1]);
|
|
@@ -54,14 +52,12 @@ function waitForProviderPublicKey(provider) {
|
|
|
54
52
|
});
|
|
55
53
|
});
|
|
56
54
|
}
|
|
57
|
-
|
|
58
|
-
async function runDelegatedCompletion(topic, providerPublicKey) {
|
|
55
|
+
async function runDelegatedCompletion(providerPublicKey) {
|
|
59
56
|
console.log("→ Loading model via delegation...");
|
|
60
57
|
const modelId = await loadModel({
|
|
61
58
|
modelSrc: LLAMA_3_2_1B_INST_Q4_0,
|
|
62
59
|
modelType: "llm",
|
|
63
60
|
delegate: {
|
|
64
|
-
topic,
|
|
65
61
|
providerPublicKey,
|
|
66
62
|
timeout: 30_000,
|
|
67
63
|
},
|
|
@@ -83,14 +79,12 @@ async function runDelegatedCompletion(topic, providerPublicKey) {
|
|
|
83
79
|
const stats = await response.stats;
|
|
84
80
|
console.log(`\n📊 Stats: ${JSON.stringify(stats)}`);
|
|
85
81
|
}
|
|
86
|
-
// ── Main ────────────────────────────────────────────────────────────
|
|
87
82
|
const provider = spawnProviderProcess();
|
|
88
83
|
try {
|
|
89
84
|
console.log("🔧 Waiting for provider to start and announce its key...\n");
|
|
90
85
|
const publicKey = await waitForProviderPublicKey(provider);
|
|
91
|
-
console.log(`\n📡 Provider ready — key: ${publicKey}`);
|
|
92
|
-
|
|
93
|
-
await runDelegatedCompletion(TOPIC, publicKey);
|
|
86
|
+
console.log(`\n📡 Provider ready — key: ${publicKey}\n`);
|
|
87
|
+
await runDelegatedCompletion(publicKey);
|
|
94
88
|
void close();
|
|
95
89
|
}
|
|
96
90
|
finally {
|
|
@@ -1,27 +1,20 @@
|
|
|
1
1
|
import { close, completion, LLAMA_3_2_1B_INST_Q4_0, loadModel, profiler, } from "@qvac/sdk";
|
|
2
|
-
const
|
|
3
|
-
if (!topicHex) {
|
|
4
|
-
console.error("❌ Usage: bun run consumer-profiled.ts <topic> <publicKey>");
|
|
5
|
-
process.exit(1);
|
|
6
|
-
}
|
|
7
|
-
const providerPublicKey = process.argv[3];
|
|
2
|
+
const providerPublicKey = process.argv[2];
|
|
8
3
|
if (!providerPublicKey) {
|
|
9
|
-
console.error("❌ Usage: bun run consumer-profiled.ts <
|
|
4
|
+
console.error("❌ Usage: bun run consumer-profiled.ts <providerPublicKey>");
|
|
10
5
|
process.exit(1);
|
|
11
6
|
}
|
|
12
7
|
try {
|
|
13
8
|
profiler.enable({ mode: "verbose", includeServerBreakdown: true });
|
|
14
9
|
console.log("✓ Profiler enabled");
|
|
15
|
-
console.log(`\n
|
|
16
|
-
console.log(`🔑 Provider: ${providerPublicKey}\n`);
|
|
10
|
+
console.log(`\n🔑 Provider: ${providerPublicKey}\n`);
|
|
17
11
|
console.log("→ Loading model (delegated, unary)...");
|
|
18
12
|
const modelId = await loadModel({
|
|
19
13
|
modelSrc: LLAMA_3_2_1B_INST_Q4_0,
|
|
20
14
|
modelType: "llm",
|
|
21
15
|
delegate: {
|
|
22
|
-
topic: topicHex,
|
|
23
16
|
providerPublicKey,
|
|
24
|
-
timeout:
|
|
17
|
+
timeout: 60_000,
|
|
25
18
|
},
|
|
26
19
|
});
|
|
27
20
|
console.log(`✓ Model loaded: ${modelId}\n`);
|
|
@@ -1,22 +1,14 @@
|
|
|
1
1
|
import { completion, LLAMA_3_2_1B_INST_Q4_0, loadModel, close, } from "@qvac/sdk";
|
|
2
|
-
|
|
3
|
-
const topicHex = process.argv[2];
|
|
4
|
-
if (!topicHex) {
|
|
5
|
-
console.error("❌ Topic hex is required. Usage: node consumer.ts <topic-hex> <provider-public-key> [consumer-seed]");
|
|
6
|
-
process.exit(1);
|
|
7
|
-
}
|
|
8
|
-
// Provider public key (required)
|
|
9
|
-
const providerPublicKey = process.argv[3];
|
|
2
|
+
const providerPublicKey = process.argv[2];
|
|
10
3
|
if (!providerPublicKey) {
|
|
11
|
-
console.error("❌ Provider public key is required. Usage: node consumer.ts <
|
|
4
|
+
console.error("❌ Provider public key is required. Usage: node consumer.ts <provider-public-key> [consumer-seed]");
|
|
12
5
|
process.exit(1);
|
|
13
6
|
}
|
|
14
7
|
try {
|
|
15
8
|
// Optional: Consumer seed for deterministic consumer identity (for firewall testing)
|
|
16
|
-
const consumerSeed = process.argv[
|
|
9
|
+
const consumerSeed = process.argv[3];
|
|
17
10
|
process.env["QVAC_HYPERSWARM_SEED"] = consumerSeed;
|
|
18
11
|
console.log(`🚀 Testing delegated inference`);
|
|
19
|
-
console.log(`📡 Topic: ${topicHex}`);
|
|
20
12
|
console.log(`🔑 Provider: ${providerPublicKey}`);
|
|
21
13
|
if (consumerSeed) {
|
|
22
14
|
console.log(`🔑 Consumer seed: ${consumerSeed.substring(0, 16)}... (deterministic identity)`);
|
|
@@ -28,9 +20,12 @@ try {
|
|
|
28
20
|
modelSrc: LLAMA_3_2_1B_INST_Q4_0,
|
|
29
21
|
modelType: "llm",
|
|
30
22
|
delegate: {
|
|
31
|
-
topic: topicHex,
|
|
32
23
|
providerPublicKey,
|
|
33
|
-
timeout
|
|
24
|
+
// Generous timeout for the first call on a cold DHT: bootstrapping
|
|
25
|
+
// hyperdht and looking up the provider's key can take 15–45s on the
|
|
26
|
+
// very first run. Subsequent connections in the same process are
|
|
27
|
+
// sub-second because the DHT is already warm.
|
|
28
|
+
timeout: 60_000,
|
|
34
29
|
fallbackToLocal: true, // Optional: Fall back to local inference if delegation fails
|
|
35
30
|
// forceNewConnection: true, // Optional: Force a new connection instead of reusing cached one
|
|
36
31
|
},
|
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
import { startQVACProvider } from "@qvac/sdk";
|
|
2
|
-
// Random topic if not provided
|
|
3
|
-
const topic = process.argv[2] ||
|
|
4
|
-
"66646f696865726f6569686a726530776a66646f696865726f6569686a726530";
|
|
5
2
|
// Optional: Seed for deterministic provider identity (64-character hex string)
|
|
6
|
-
const seed = process.argv[
|
|
7
|
-
|
|
3
|
+
const seed = process.argv[2];
|
|
4
|
+
if (seed) {
|
|
5
|
+
process.env["QVAC_HYPERSWARM_SEED"] = seed;
|
|
6
|
+
}
|
|
8
7
|
// Optional: Consumer public key for firewall (allow only this consumer)
|
|
9
|
-
const allowedConsumerPublicKey = process.argv[
|
|
10
|
-
console.log(`🚀 Starting provider service
|
|
8
|
+
const allowedConsumerPublicKey = process.argv[3];
|
|
9
|
+
console.log(`🚀 Starting provider service...`);
|
|
11
10
|
try {
|
|
12
11
|
if (allowedConsumerPublicKey) {
|
|
13
12
|
console.log(`🔒 Firewall enabled: only allowing consumer ${allowedConsumerPublicKey}`);
|
|
14
13
|
}
|
|
15
|
-
// Start the provider service with optional firewall and seed
|
|
16
14
|
const response = await startQVACProvider({
|
|
17
|
-
topic,
|
|
18
15
|
firewall: allowedConsumerPublicKey
|
|
19
16
|
? {
|
|
20
17
|
mode: "allow",
|
|
@@ -26,14 +23,13 @@ try {
|
|
|
26
23
|
console.log("🔗 Provider is now available for delegated inference requests");
|
|
27
24
|
console.log("");
|
|
28
25
|
console.log("📋 Connection Details:");
|
|
29
|
-
console.log(`
|
|
30
|
-
console.log(` 🆔 Provider Public Key (unique): ${response.publicKey}`);
|
|
26
|
+
console.log(` 🆔 Provider Public Key: ${response.publicKey}`);
|
|
31
27
|
console.log("");
|
|
32
28
|
console.log("💡 Consumer command:");
|
|
33
|
-
console.log(` node consumer.ts ${
|
|
29
|
+
console.log(` node consumer.ts ${response.publicKey}`);
|
|
34
30
|
console.log("");
|
|
35
31
|
console.log("💡 To reproduce this provider identity:");
|
|
36
|
-
console.log(` node provider.ts ${
|
|
32
|
+
console.log(` node provider.ts ${seed || "<random-seed>"}`);
|
|
37
33
|
if (!seed) {
|
|
38
34
|
console.log(" (Note: seed was random this time, set one for reproducible identity)");
|
|
39
35
|
}
|
|
@@ -41,9 +37,8 @@ try {
|
|
|
41
37
|
console.log("🔒 For firewall testing:");
|
|
42
38
|
console.log(" 1. Generate a consumer seed (64-char hex)");
|
|
43
39
|
console.log(" 2. Get consumer public key: getConsumerPublicKey(consumerSeed)");
|
|
44
|
-
console.log(" 3. Restart provider with consumer public key as
|
|
45
|
-
console.log(` 4. Run consumer with: node consumer.ts ${
|
|
46
|
-
// Keep the process running
|
|
40
|
+
console.log(" 3. Restart provider with consumer public key as 2nd argument");
|
|
41
|
+
console.log(` 4. Run consumer with: node consumer.ts ${response.publicKey} <consumer-seed>`);
|
|
47
42
|
console.log("📡 Provider is running... Press Ctrl+C to stop");
|
|
48
43
|
process.on("SIGINT", () => {
|
|
49
44
|
console.log("\n🛑 Provider service stopped");
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { loadModel, unloadModel, diffusion, FLUX_2_KLEIN_4B_Q4_0, FLUX_2_KLEIN_4B_VAE, QWEN3_4B_Q4_K_M, } from "@qvac/sdk";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
// img2img with FLUX.2 [klein] split-layout — uses in-context conditioning ("flux2_flow").
|
|
5
|
+
const inputPath = process.argv[2];
|
|
6
|
+
const prompt = process.argv[3] || "oil painting style, vibrant colors";
|
|
7
|
+
const outputDir = process.argv[4] || ".";
|
|
8
|
+
const diffusionModelSrc = process.argv[5] || FLUX_2_KLEIN_4B_Q4_0;
|
|
9
|
+
const llmModelSrc = process.argv[6] || QWEN3_4B_Q4_K_M;
|
|
10
|
+
const vaeModelSrc = process.argv[7] || FLUX_2_KLEIN_4B_VAE;
|
|
11
|
+
if (!inputPath) {
|
|
12
|
+
console.error("❌ Error: input image path is required");
|
|
13
|
+
console.error("Usage: bun run bare:example dist/examples/diffusion-flux2-klein-img2img.js <inputImage> [prompt] [outputDir] [diffusionModelSrc] [llmModelSrc] [vaeModelSrc]");
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
try {
|
|
17
|
+
console.log("Loading FLUX.2 [klein] split-layout model...");
|
|
18
|
+
const modelId = await loadModel({
|
|
19
|
+
modelSrc: diffusionModelSrc,
|
|
20
|
+
modelType: "diffusion",
|
|
21
|
+
modelConfig: {
|
|
22
|
+
device: "gpu",
|
|
23
|
+
threads: 4,
|
|
24
|
+
llmModelSrc,
|
|
25
|
+
vaeModelSrc,
|
|
26
|
+
prediction: "flux2_flow",
|
|
27
|
+
},
|
|
28
|
+
onProgress: (p) => console.log(`Loading: ${p.percentage.toFixed(1)}%`),
|
|
29
|
+
});
|
|
30
|
+
console.log(`Model loaded: ${modelId}`);
|
|
31
|
+
const init_image = new Uint8Array(fs.readFileSync(inputPath));
|
|
32
|
+
console.log(`\nTransforming "${inputPath}" with prompt: "${prompt}"`);
|
|
33
|
+
const { progressStream, outputs, stats } = diffusion({
|
|
34
|
+
modelId,
|
|
35
|
+
prompt,
|
|
36
|
+
init_image,
|
|
37
|
+
steps: 20,
|
|
38
|
+
guidance: 3.5,
|
|
39
|
+
cfg_scale: 1,
|
|
40
|
+
seed: -1,
|
|
41
|
+
});
|
|
42
|
+
for await (const { step, totalSteps } of progressStream) {
|
|
43
|
+
process.stdout.write(`\rStep ${step}/${totalSteps}`);
|
|
44
|
+
}
|
|
45
|
+
console.log();
|
|
46
|
+
const buffers = await outputs;
|
|
47
|
+
for (let i = 0; i < buffers.length; i++) {
|
|
48
|
+
const outputPath = path.join(outputDir, `flux2_img2img_${i}.png`);
|
|
49
|
+
fs.writeFileSync(outputPath, buffers[i]);
|
|
50
|
+
console.log(`Saved: ${outputPath}`);
|
|
51
|
+
}
|
|
52
|
+
console.log("\nStats:", await stats);
|
|
53
|
+
await unloadModel({ modelId, clearStorage: false });
|
|
54
|
+
console.log("Done.");
|
|
55
|
+
process.exit(0);
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
console.error("❌ Error:", error);
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { loadModel, unloadModel, diffusion, SD_V2_1_1B_Q8_0 } from "@qvac/sdk";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
// img2img example — transforms an input image guided by a text prompt.
|
|
5
|
+
const inputPath = process.argv[2];
|
|
6
|
+
const prompt = process.argv[3] || "oil painting style, vibrant colors";
|
|
7
|
+
const outputDir = process.argv[4] || ".";
|
|
8
|
+
const modelSrc = process.argv[5] || SD_V2_1_1B_Q8_0;
|
|
9
|
+
if (!inputPath) {
|
|
10
|
+
console.error("❌ Error: input image path is required");
|
|
11
|
+
console.error("Usage: bun run bare:example dist/examples/diffusion-img2img.js <inputImage> [prompt] [outputDir] [modelSrc]");
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
try {
|
|
15
|
+
console.log("Loading diffusion model...");
|
|
16
|
+
const modelId = await loadModel({
|
|
17
|
+
modelSrc,
|
|
18
|
+
modelType: "diffusion",
|
|
19
|
+
});
|
|
20
|
+
console.log(`Model loaded: ${modelId}`);
|
|
21
|
+
const init_image = new Uint8Array(fs.readFileSync(inputPath));
|
|
22
|
+
console.log(`\nTransforming "${inputPath}" with prompt: "${prompt}"`);
|
|
23
|
+
const { progressStream, outputs, stats } = diffusion({
|
|
24
|
+
modelId,
|
|
25
|
+
prompt,
|
|
26
|
+
init_image,
|
|
27
|
+
strength: 0.5,
|
|
28
|
+
steps: 30,
|
|
29
|
+
seed: -1,
|
|
30
|
+
});
|
|
31
|
+
for await (const { step, totalSteps } of progressStream) {
|
|
32
|
+
process.stdout.write(`\rStep ${step}/${totalSteps}`);
|
|
33
|
+
}
|
|
34
|
+
console.log();
|
|
35
|
+
const buffers = await outputs;
|
|
36
|
+
for (let i = 0; i < buffers.length; i++) {
|
|
37
|
+
const outputPath = path.join(outputDir, `img2img_${i}.png`);
|
|
38
|
+
fs.writeFileSync(outputPath, buffers[i]);
|
|
39
|
+
console.log(`Saved: ${outputPath}`);
|
|
40
|
+
}
|
|
41
|
+
console.log("\nStats:", await stats);
|
|
42
|
+
await unloadModel({ modelId, clearStorage: false });
|
|
43
|
+
console.log("Done.");
|
|
44
|
+
process.exit(0);
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
console.error("❌ Error:", error);
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
@@ -11,8 +11,8 @@ try {
|
|
|
11
11
|
},
|
|
12
12
|
});
|
|
13
13
|
console.log("🧠 Testing KV Cache functionality...\n");
|
|
14
|
-
// First conversation with cache enabled
|
|
15
|
-
console.log("📝 First conversation (building cache):");
|
|
14
|
+
// First conversation with auto-keyed cache enabled
|
|
15
|
+
console.log("📝 First conversation (building cache for the next turn):");
|
|
16
16
|
const history1 = [
|
|
17
17
|
{ role: "user", content: "What is the capital of France?" },
|
|
18
18
|
];
|
|
@@ -22,24 +22,23 @@ try {
|
|
|
22
22
|
stream: true,
|
|
23
23
|
kvCache: true,
|
|
24
24
|
}); // kvCache = true
|
|
25
|
-
let response1 = "";
|
|
26
25
|
for await (const token of result1.tokenStream) {
|
|
27
|
-
response1 += token;
|
|
28
26
|
process.stdout.write(token);
|
|
29
27
|
}
|
|
30
|
-
const
|
|
28
|
+
const final1 = await result1.final;
|
|
29
|
+
const stats1 = final1.stats;
|
|
31
30
|
console.log(`\n⏱️ First completion stats: ${JSON.stringify(stats1)}\n`);
|
|
32
|
-
// Continue conversation (should reuse
|
|
33
|
-
console.log("🔄 Continuing conversation (reusing cache):");
|
|
31
|
+
// Continue conversation (should reuse the completed first-turn cache).
|
|
32
|
+
console.log("🔄 Continuing conversation (reusing previous turn cache):");
|
|
34
33
|
const history2 = [
|
|
35
34
|
{ role: "user", content: "What is the capital of France?" },
|
|
36
|
-
{ role: "assistant", content:
|
|
35
|
+
{ role: "assistant", content: final1.cacheableAssistantContent ?? final1.contentText },
|
|
37
36
|
{ role: "user", content: "What about Germany?" },
|
|
38
37
|
];
|
|
39
|
-
//
|
|
40
|
-
// 1. Find
|
|
41
|
-
// 2. Load that cache and process the new "What about Germany?"
|
|
42
|
-
// 3. Save the updated cache and rename it to include
|
|
38
|
+
// Auto-keyed caching should:
|
|
39
|
+
// 1. Find the cache saved after turn 1 under [user, assistant]
|
|
40
|
+
// 2. Load that cache and process only the new "What about Germany?" user turn
|
|
41
|
+
// 3. Save the updated cache and rename it to include the new assistant response
|
|
43
42
|
const result2 = completion({
|
|
44
43
|
modelId,
|
|
45
44
|
history: history2,
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { completion, deleteCache, LLAMA_3_2_1B_INST_Q4_0, loadModel, unloadModel, VERBOSITY, } from "@qvac/sdk";
|
|
2
|
+
const sharedCacheKey = "llamacpp-cache-demo-shared";
|
|
3
|
+
const isolatedCacheKey = "llamacpp-cache-demo-isolated";
|
|
4
|
+
const systemPrompt = {
|
|
5
|
+
role: "system",
|
|
6
|
+
content: "You are a concise travel assistant. Keep track of the user's preferences across turns.",
|
|
7
|
+
};
|
|
8
|
+
function printStats(stats) {
|
|
9
|
+
console.log("\nPerformance Stats:", {
|
|
10
|
+
timeToFirstToken: stats?.timeToFirstToken,
|
|
11
|
+
tokensPerSecond: stats?.tokensPerSecond,
|
|
12
|
+
cacheTokens: stats?.cacheTokens,
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
async function runCachedCompletion(params) {
|
|
16
|
+
console.log(`\n=== ${params.label} ===`);
|
|
17
|
+
console.log(`Cache key: ${params.kvCache || "disabled"}`);
|
|
18
|
+
console.log("AI Response:");
|
|
19
|
+
const result = completion({
|
|
20
|
+
modelId: params.modelId,
|
|
21
|
+
history: params.history,
|
|
22
|
+
stream: true,
|
|
23
|
+
kvCache: params.kvCache,
|
|
24
|
+
});
|
|
25
|
+
let text = "";
|
|
26
|
+
for await (const token of result.tokenStream) {
|
|
27
|
+
text += token;
|
|
28
|
+
process.stdout.write(token);
|
|
29
|
+
}
|
|
30
|
+
const stats = await result.stats;
|
|
31
|
+
printStats(stats);
|
|
32
|
+
return { text, stats };
|
|
33
|
+
}
|
|
34
|
+
let modelId;
|
|
35
|
+
try {
|
|
36
|
+
console.log("Loading llama.cpp model with cache support...");
|
|
37
|
+
modelId = await loadModel({
|
|
38
|
+
modelSrc: LLAMA_3_2_1B_INST_Q4_0,
|
|
39
|
+
modelType: "llm",
|
|
40
|
+
modelConfig: {
|
|
41
|
+
ctx_size: 4096,
|
|
42
|
+
verbosity: VERBOSITY.ERROR,
|
|
43
|
+
},
|
|
44
|
+
onProgress: (progress) => {
|
|
45
|
+
console.log(`Loading: ${progress.percentage.toFixed(1)}%`);
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
console.log(`Model loaded successfully. Model ID: ${modelId}`);
|
|
49
|
+
await deleteCache({ kvCacheKey: sharedCacheKey });
|
|
50
|
+
await deleteCache({ kvCacheKey: isolatedCacheKey });
|
|
51
|
+
const firstUserMessage = {
|
|
52
|
+
role: "user",
|
|
53
|
+
content: "I am planning a weekend in Lisbon. I prefer museums, seafood, and walking routes. Suggest a day plan in 3 bullets.",
|
|
54
|
+
};
|
|
55
|
+
const firstTurn = await runCachedCompletion({
|
|
56
|
+
label: "Turn 1: create a named cache",
|
|
57
|
+
modelId,
|
|
58
|
+
kvCache: sharedCacheKey,
|
|
59
|
+
history: [systemPrompt, firstUserMessage],
|
|
60
|
+
});
|
|
61
|
+
await runCachedCompletion({
|
|
62
|
+
label: "Turn 2: reuse the same cache key",
|
|
63
|
+
modelId,
|
|
64
|
+
kvCache: sharedCacheKey,
|
|
65
|
+
history: [
|
|
66
|
+
systemPrompt,
|
|
67
|
+
firstUserMessage,
|
|
68
|
+
{ role: "assistant", content: firstTurn.text.trim() },
|
|
69
|
+
{
|
|
70
|
+
role: "user",
|
|
71
|
+
content: "Now revise the plan for a rainy day, but keep the same preferences.",
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
});
|
|
75
|
+
await runCachedCompletion({
|
|
76
|
+
label: "Turn 3: use a different cache key for an isolated session",
|
|
77
|
+
modelId,
|
|
78
|
+
kvCache: isolatedCacheKey,
|
|
79
|
+
history: [
|
|
80
|
+
systemPrompt,
|
|
81
|
+
{
|
|
82
|
+
role: "user",
|
|
83
|
+
content: "I am planning a weekend in Berlin. I prefer nightlife and late starts. Suggest a day plan in 3 bullets.",
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
});
|
|
87
|
+
console.log("\nSummary:");
|
|
88
|
+
console.log(`- Reusing "${sharedCacheKey}" keeps conversation context across turns.`);
|
|
89
|
+
console.log(`- Switching to "${isolatedCacheKey}" starts a separate cache session.`);
|
|
90
|
+
console.log('- Use deleteCache({ kvCacheKey: "your-session" }) to clear a saved session.');
|
|
91
|
+
await deleteCache({ kvCacheKey: sharedCacheKey });
|
|
92
|
+
await deleteCache({ kvCacheKey: isolatedCacheKey });
|
|
93
|
+
await unloadModel({ modelId, clearStorage: false });
|
|
94
|
+
process.exit(0);
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
if (modelId) {
|
|
98
|
+
try {
|
|
99
|
+
await unloadModel({ modelId, clearStorage: false });
|
|
100
|
+
}
|
|
101
|
+
catch (cleanupError) {
|
|
102
|
+
console.warn("⚠️ cleanup failed:", cleanupError);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
console.error("❌ Error:", error);
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|