@qvac/sdk 0.1.0-dev.1760648187.328e967
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/LICENSE +202 -0
- package/README.md +301 -0
- package/dist/client/api/cancel.d.ts +25 -0
- package/dist/client/api/cancel.js +37 -0
- package/dist/client/api/completion-stream.d.ts +50 -0
- package/dist/client/api/completion-stream.js +103 -0
- package/dist/client/api/download-asset.d.ts +39 -0
- package/dist/client/api/download-asset.js +72 -0
- package/dist/client/api/embed.d.ts +11 -0
- package/dist/client/api/embed.js +24 -0
- package/dist/client/api/index.d.ts +13 -0
- package/dist/client/api/index.js +12 -0
- package/dist/client/api/load-model.d.ts +98 -0
- package/dist/client/api/load-model.js +154 -0
- package/dist/client/api/logging-stream.d.ts +21 -0
- package/dist/client/api/logging-stream.js +32 -0
- package/dist/client/api/ping.d.ts +11 -0
- package/dist/client/api/ping.js +18 -0
- package/dist/client/api/provide.d.ts +18 -0
- package/dist/client/api/provide.js +27 -0
- package/dist/client/api/rag.d.ts +42 -0
- package/dist/client/api/rag.js +97 -0
- package/dist/client/api/transcribe.d.ts +24 -0
- package/dist/client/api/transcribe.js +52 -0
- package/dist/client/api/translate.d.ts +47 -0
- package/dist/client/api/translate.js +114 -0
- package/dist/client/api/unload-model.d.ts +11 -0
- package/dist/client/api/unload-model.js +26 -0
- package/dist/client/index.d.ts +2 -0
- package/dist/client/index.js +1 -0
- package/dist/client/logging-stream-registry.d.ts +5 -0
- package/dist/client/logging-stream-registry.js +60 -0
- package/dist/client/rpc/bare-client.d.ts +112 -0
- package/dist/client/rpc/bare-client.js +82 -0
- package/dist/client/rpc/bare-rpc-client.d.ts +4 -0
- package/dist/client/rpc/bare-rpc-client.js +87 -0
- package/dist/client/rpc/expo-rpc-client.d.ts +3 -0
- package/dist/client/rpc/expo-rpc-client.js +57 -0
- package/dist/client/rpc/node-rpc-client.d.ts +9 -0
- package/dist/client/rpc/node-rpc-client.js +99 -0
- package/dist/client/rpc/rpc-client.d.ts +5 -0
- package/dist/client/rpc/rpc-client.js +91 -0
- package/dist/client/rpc/rpc-error.d.ts +19 -0
- package/dist/client/rpc/rpc-error.js +39 -0
- package/dist/constants/audio.d.ts +3 -0
- package/dist/constants/audio.js +17 -0
- package/dist/constants/index.d.ts +2 -0
- package/dist/constants/index.js +1 -0
- package/dist/examples/delegated-inference/consumer.d.ts +2 -0
- package/dist/examples/delegated-inference/consumer.js +56 -0
- package/dist/examples/delegated-inference/provider.d.ts +2 -0
- package/dist/examples/delegated-inference/provider.js +57 -0
- package/dist/examples/download-with-cancel.d.ts +2 -0
- package/dist/examples/download-with-cancel.js +46 -0
- package/dist/examples/embed-hyperdrive.d.ts +2 -0
- package/dist/examples/embed-hyperdrive.js +19 -0
- package/dist/examples/kv-cache-example.d.ts +2 -0
- package/dist/examples/kv-cache-example.js +74 -0
- package/dist/examples/llamacpp-file-logging.d.ts +2 -0
- package/dist/examples/llamacpp-file-logging.js +62 -0
- package/dist/examples/llamacpp-filesystem.d.ts +2 -0
- package/dist/examples/llamacpp-filesystem.js +40 -0
- package/dist/examples/llamacpp-http.d.ts +2 -0
- package/dist/examples/llamacpp-http.js +41 -0
- package/dist/examples/llamacpp-hyperdrive.d.ts +2 -0
- package/dist/examples/llamacpp-hyperdrive.js +39 -0
- package/dist/examples/llamacpp-multimodal.d.ts +2 -0
- package/dist/examples/llamacpp-multimodal.js +62 -0
- package/dist/examples/llamacpp-native-tools.d.ts +2 -0
- package/dist/examples/llamacpp-native-tools.js +64 -0
- package/dist/examples/llamacpp-tools-routing.d.ts +2 -0
- package/dist/examples/llamacpp-tools-routing.js +364 -0
- package/dist/examples/llamacpp-tools.d.ts +2 -0
- package/dist/examples/llamacpp-tools.js +81 -0
- package/dist/examples/multi-model-demo.d.ts +2 -0
- package/dist/examples/multi-model-demo.js +75 -0
- package/dist/examples/parallel-download.d.ts +2 -0
- package/dist/examples/parallel-download.js +21 -0
- package/dist/examples/rag/rag-chromadb.d.ts +2 -0
- package/dist/examples/rag/rag-chromadb.js +130 -0
- package/dist/examples/rag/rag-hyperdb-workspaces.d.ts +2 -0
- package/dist/examples/rag/rag-hyperdb-workspaces.js +106 -0
- package/dist/examples/rag/rag-hyperdb.d.ts +2 -0
- package/dist/examples/rag/rag-hyperdb.js +50 -0
- package/dist/examples/rag/rag-lancedb.d.ts +2 -0
- package/dist/examples/rag/rag-lancedb.js +95 -0
- package/dist/examples/rag/rag-sqlite.d.ts +2 -0
- package/dist/examples/rag/rag-sqlite.js +107 -0
- package/dist/examples/seed-hyperdrive.d.ts +2 -0
- package/dist/examples/seed-hyperdrive.js +21 -0
- package/dist/examples/translation/translation-indic.d.ts +2 -0
- package/dist/examples/translation/translation-indic.js +30 -0
- package/dist/examples/translation/translation-llm-context.d.ts +2 -0
- package/dist/examples/translation/translation-llm-context.js +30 -0
- package/dist/examples/translation/translation-llm.d.ts +2 -0
- package/dist/examples/translation/translation-llm.js +38 -0
- package/dist/examples/translation/translation-opus.d.ts +2 -0
- package/dist/examples/translation/translation-opus.js +30 -0
- package/dist/examples/translation/translation-stream.d.ts +2 -0
- package/dist/examples/translation/translation-stream.js +35 -0
- package/dist/examples/whispercpp-filesystem.d.ts +2 -0
- package/dist/examples/whispercpp-filesystem.js +43 -0
- package/dist/examples/whispercpp-microphone-record.d.ts +2 -0
- package/dist/examples/whispercpp-microphone-record.js +311 -0
- package/dist/expo/plugins/index.d.ts +5 -0
- package/dist/expo/plugins/index.js +5 -0
- package/dist/expo/plugins/withMobileBundle.d.ts +8 -0
- package/dist/expo/plugins/withMobileBundle.js +60 -0
- package/dist/expo/plugins/withOpenCL.d.ts +9 -0
- package/dist/expo/plugins/withOpenCL.js +118 -0
- package/dist/expo/plugins/withQvacSDK.d.ts +9 -0
- package/dist/expo/plugins/withQvacSDK.js +13 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +8 -0
- package/dist/logging/base-logger.d.ts +7 -0
- package/dist/logging/base-logger.js +55 -0
- package/dist/logging/index.d.ts +4 -0
- package/dist/logging/index.js +2 -0
- package/dist/logging/logger.d.ts +5 -0
- package/dist/logging/logger.js +28 -0
- package/dist/logging/stream-logger.d.ts +3 -0
- package/dist/logging/stream-logger.js +9 -0
- package/dist/logging/transport.d.ts +3 -0
- package/dist/logging/transport.js +15 -0
- package/dist/logging/types.d.ts +18 -0
- package/dist/logging/types.js +1 -0
- package/dist/logging/utils.d.ts +4 -0
- package/dist/logging/utils.js +47 -0
- package/dist/models/hyperdrive/index.d.ts +2 -0
- package/dist/models/hyperdrive/index.js +2 -0
- package/dist/models/hyperdrive/models.d.ts +475 -0
- package/dist/models/hyperdrive/models.js +534 -0
- package/dist/schemas/cancel.d.ts +33 -0
- package/dist/schemas/cancel.js +25 -0
- package/dist/schemas/common.d.ts +626 -0
- package/dist/schemas/common.js +47 -0
- package/dist/schemas/completion-stream.d.ts +125 -0
- package/dist/schemas/completion-stream.js +53 -0
- package/dist/schemas/delegate.d.ts +9 -0
- package/dist/schemas/delegate.js +9 -0
- package/dist/schemas/download-asset.d.ts +75 -0
- package/dist/schemas/download-asset.js +43 -0
- package/dist/schemas/embed.d.ts +20 -0
- package/dist/schemas/embed.js +14 -0
- package/dist/schemas/error.d.ts +13 -0
- package/dist/schemas/error.js +35 -0
- package/dist/schemas/index.d.ts +19 -0
- package/dist/schemas/index.js +19 -0
- package/dist/schemas/llamacpp-config.d.ts +30 -0
- package/dist/schemas/llamacpp-config.js +39 -0
- package/dist/schemas/load-model.d.ts +1259 -0
- package/dist/schemas/load-model.js +108 -0
- package/dist/schemas/logging-stream.d.ts +27 -0
- package/dist/schemas/logging-stream.js +16 -0
- package/dist/schemas/ping.d.ts +11 -0
- package/dist/schemas/ping.js +8 -0
- package/dist/schemas/provide.d.ts +43 -0
- package/dist/schemas/provide.js +25 -0
- package/dist/schemas/rag.d.ts +159 -0
- package/dist/schemas/rag.js +78 -0
- package/dist/schemas/transcription.d.ts +24 -0
- package/dist/schemas/transcription.js +15 -0
- package/dist/schemas/translate.d.ts +82 -0
- package/dist/schemas/translate.js +42 -0
- package/dist/schemas/translation-config.d.ts +83 -0
- package/dist/schemas/translation-config.js +46 -0
- package/dist/schemas/unload-model.d.ts +19 -0
- package/dist/schemas/unload-model.js +13 -0
- package/dist/schemas/whispercpp-config.d.ts +25 -0
- package/dist/schemas/whispercpp-config.js +18 -0
- package/dist/server/bare/addons/cancel.d.ts +3 -0
- package/dist/server/bare/addons/cancel.js +12 -0
- package/dist/server/bare/addons/index.d.ts +4 -0
- package/dist/server/bare/addons/index.js +3 -0
- package/dist/server/bare/addons/llamacpp/create-model.d.ts +5 -0
- package/dist/server/bare/addons/llamacpp/create-model.js +57 -0
- package/dist/server/bare/addons/llamacpp/handlers/completion-stream.d.ts +3 -0
- package/dist/server/bare/addons/llamacpp/handlers/completion-stream.js +65 -0
- package/dist/server/bare/addons/llamacpp/handlers/embed.d.ts +4 -0
- package/dist/server/bare/addons/llamacpp/handlers/embed.js +40 -0
- package/dist/server/bare/addons/llamacpp/index.d.ts +4 -0
- package/dist/server/bare/addons/llamacpp/index.js +3 -0
- package/dist/server/bare/addons/llamacpp/kv-cache-utils.d.ts +19 -0
- package/dist/server/bare/addons/llamacpp/kv-cache-utils.js +46 -0
- package/dist/server/bare/addons/load-model.d.ts +3 -0
- package/dist/server/bare/addons/load-model.js +55 -0
- package/dist/server/bare/addons/translation/create-model.d.ts +4 -0
- package/dist/server/bare/addons/translation/create-model.js +45 -0
- package/dist/server/bare/addons/translation/handlers/translate.d.ts +3 -0
- package/dist/server/bare/addons/translation/handlers/translate.js +86 -0
- package/dist/server/bare/addons/translation/index.d.ts +3 -0
- package/dist/server/bare/addons/translation/index.js +2 -0
- package/dist/server/bare/addons/unload-model.d.ts +3 -0
- package/dist/server/bare/addons/unload-model.js +20 -0
- package/dist/server/bare/addons/whispercpp/create-model.d.ts +6 -0
- package/dist/server/bare/addons/whispercpp/create-model.js +55 -0
- package/dist/server/bare/addons/whispercpp/handlers/transcribe-stream.d.ts +3 -0
- package/dist/server/bare/addons/whispercpp/handlers/transcribe-stream.js +42 -0
- package/dist/server/bare/addons/whispercpp/index.d.ts +3 -0
- package/dist/server/bare/addons/whispercpp/index.js +2 -0
- package/dist/server/bare/delegate-rpc-client.d.ts +4 -0
- package/dist/server/bare/delegate-rpc-client.js +70 -0
- package/dist/server/bare/hyperswarm.d.ts +7 -0
- package/dist/server/bare/hyperswarm.js +62 -0
- package/dist/server/bare/rag-hyperdb/handlers/delete-embeddings.d.ts +3 -0
- package/dist/server/bare/rag-hyperdb/handlers/delete-embeddings.js +12 -0
- package/dist/server/bare/rag-hyperdb/handlers/save-embeddings.d.ts +6 -0
- package/dist/server/bare/rag-hyperdb/handlers/save-embeddings.js +16 -0
- package/dist/server/bare/rag-hyperdb/handlers/search.d.ts +3 -0
- package/dist/server/bare/rag-hyperdb/handlers/search.js +15 -0
- package/dist/server/bare/rag-hyperdb/index.d.ts +5 -0
- package/dist/server/bare/rag-hyperdb/index.js +4 -0
- package/dist/server/bare/rag-hyperdb/rag-manager.d.ts +5 -0
- package/dist/server/bare/rag-hyperdb/rag-manager.js +61 -0
- package/dist/server/bare/registry/logging-stream-registry.d.ts +12 -0
- package/dist/server/bare/registry/logging-stream-registry.js +46 -0
- package/dist/server/bare/registry/model-registry.d.ts +64 -0
- package/dist/server/bare/registry/model-registry.js +95 -0
- package/dist/server/error-handlers.d.ts +4 -0
- package/dist/server/error-handlers.js +27 -0
- package/dist/server/http-server.d.ts +2 -0
- package/dist/server/http-server.js +189 -0
- package/dist/server/rpc/create-server.d.ts +4 -0
- package/dist/server/rpc/create-server.js +19 -0
- package/dist/server/rpc/handle-request.d.ts +12 -0
- package/dist/server/rpc/handle-request.js +220 -0
- package/dist/server/rpc/handlers/cancelHandler.d.ts +3 -0
- package/dist/server/rpc/handlers/cancelHandler.js +27 -0
- package/dist/server/rpc/handlers/completion-stream-delegated.d.ts +3 -0
- package/dist/server/rpc/handlers/completion-stream-delegated.js +30 -0
- package/dist/server/rpc/handlers/completion-stream.d.ts +3 -0
- package/dist/server/rpc/handlers/completion-stream.js +52 -0
- package/dist/server/rpc/handlers/download-asset.d.ts +3 -0
- package/dist/server/rpc/handlers/download-asset.js +21 -0
- package/dist/server/rpc/handlers/embed.d.ts +3 -0
- package/dist/server/rpc/handlers/embed.js +21 -0
- package/dist/server/rpc/handlers/index.d.ts +23 -0
- package/dist/server/rpc/handlers/index.js +22 -0
- package/dist/server/rpc/handlers/load-model/download-manager.d.ts +31 -0
- package/dist/server/rpc/handlers/load-model/download-manager.js +88 -0
- package/dist/server/rpc/handlers/load-model/http.d.ts +3 -0
- package/dist/server/rpc/handlers/load-model/http.js +337 -0
- package/dist/server/rpc/handlers/load-model/hyperdrive.d.ts +4 -0
- package/dist/server/rpc/handlers/load-model/hyperdrive.js +332 -0
- package/dist/server/rpc/handlers/load-model/index.d.ts +4 -0
- package/dist/server/rpc/handlers/load-model/index.js +3 -0
- package/dist/server/rpc/handlers/load-model/resolve.d.ts +3 -0
- package/dist/server/rpc/handlers/load-model/resolve.js +121 -0
- package/dist/server/rpc/handlers/load-model-delegated.d.ts +3 -0
- package/dist/server/rpc/handlers/load-model-delegated.js +93 -0
- package/dist/server/rpc/handlers/load-model.d.ts +3 -0
- package/dist/server/rpc/handlers/load-model.js +41 -0
- package/dist/server/rpc/handlers/logging-stream.d.ts +3 -0
- package/dist/server/rpc/handlers/logging-stream.js +37 -0
- package/dist/server/rpc/handlers/provideHandler/connection.d.ts +3 -0
- package/dist/server/rpc/handlers/provideHandler/connection.js +25 -0
- package/dist/server/rpc/handlers/provideHandler/handler.d.ts +3 -0
- package/dist/server/rpc/handlers/provideHandler/handler.js +50 -0
- package/dist/server/rpc/handlers/provideHandler/proxy.d.ts +3 -0
- package/dist/server/rpc/handlers/provideHandler/proxy.js +22 -0
- package/dist/server/rpc/handlers/provideHandler.d.ts +2 -0
- package/dist/server/rpc/handlers/provideHandler.js +2 -0
- package/dist/server/rpc/handlers/rag.d.ts +3 -0
- package/dist/server/rpc/handlers/rag.js +67 -0
- package/dist/server/rpc/handlers/transcribe-stream.d.ts +3 -0
- package/dist/server/rpc/handlers/transcribe-stream.js +26 -0
- package/dist/server/rpc/handlers/translate.d.ts +3 -0
- package/dist/server/rpc/handlers/translate.js +51 -0
- package/dist/server/rpc/handlers/unload-model.d.ts +3 -0
- package/dist/server/rpc/handlers/unload-model.js +20 -0
- package/dist/server/rpc/index.d.ts +3 -0
- package/dist/server/rpc/index.js +2 -0
- package/dist/server/utils/audio/decoder.d.ts +4 -0
- package/dist/server/utils/audio/decoder.js +41 -0
- package/dist/server/utils/cache.d.ts +15 -0
- package/dist/server/utils/cache.js +32 -0
- package/dist/server/utils/hash.d.ts +5 -0
- package/dist/server/utils/hash.js +11 -0
- package/dist/server/utils/index.d.ts +5 -0
- package/dist/server/utils/index.js +4 -0
- package/dist/server/utils/model-path.d.ts +5 -0
- package/dist/server/utils/model-path.js +7 -0
- package/dist/server/worker.d.ts +6 -0
- package/dist/server/worker.js +77 -0
- package/dist/utils/withTimeout.d.ts +11 -0
- package/dist/utils/withTimeout.js +37 -0
- package/package.json +129 -0
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
import { loadModel, completion, QWEN_3_1_7B_INST_Q4, unloadModel, } from "@qvac/sdk";
|
|
2
|
+
try {
|
|
3
|
+
const modelId = await loadModel({
|
|
4
|
+
modelSrc: QWEN_3_1_7B_INST_Q4,
|
|
5
|
+
modelType: "llm",
|
|
6
|
+
modelConfig: {
|
|
7
|
+
ctx_size: 4096,
|
|
8
|
+
},
|
|
9
|
+
onProgress: (progress) => {
|
|
10
|
+
console.log(progress);
|
|
11
|
+
},
|
|
12
|
+
});
|
|
13
|
+
const base = [
|
|
14
|
+
{
|
|
15
|
+
role: "system",
|
|
16
|
+
content: `
|
|
17
|
+
/no_think
|
|
18
|
+
Output exactly one word based on the user's request. Choose from:
|
|
19
|
+
|
|
20
|
+
health - for health metrics and biomarkers:
|
|
21
|
+
Examples: "blood sugar is one hundred twenty", "blood pressure one forty over ninety", "heart rate seventy bpm", "weight one fifty lbs", "temperature ninety eight point six"
|
|
22
|
+
|
|
23
|
+
sleep - for sleep related activities:
|
|
24
|
+
Examples: "slept eight hours", "woke up at seven", "bedtime eleven pm", "sleep quality good", "took a nap"
|
|
25
|
+
|
|
26
|
+
exercise - for physical exercise and workouts:
|
|
27
|
+
Examples: "went for a run", "did yoga", "lifted weights", "gym session", "played tennis", "workout completed"
|
|
28
|
+
|
|
29
|
+
wellness - for mood, stress, and general wellbeing:
|
|
30
|
+
Examples: "feeling stressed", "recovery score", "strain level high", "mood is good", "anxiety level", "energy low"
|
|
31
|
+
|
|
32
|
+
steps - for step counting and walking activities:
|
|
33
|
+
Examples: "walked five thousand steps", "did ten thousand steps", "walking for thirty minutes", "step goal reached"
|
|
34
|
+
|
|
35
|
+
meal - for meal logging and food intake:
|
|
36
|
+
Examples: "ate breakfast", "had a sandwich", "two fifty g steak", "drank coffee", "snack apple"
|
|
37
|
+
|
|
38
|
+
general - for everything else:
|
|
39
|
+
Examples: "how are you?", "what's the weather?", "help me", "explain something"
|
|
40
|
+
|
|
41
|
+
It's critical that you output EXACTLY "log:" followed by one of these seven words: health, sleep, exercise, wellness, steps, meal, general.
|
|
42
|
+
|
|
43
|
+
Examples of correct output:
|
|
44
|
+
log:health
|
|
45
|
+
log:sleep
|
|
46
|
+
log:exercise
|
|
47
|
+
log:wellness
|
|
48
|
+
log:steps
|
|
49
|
+
log:meal
|
|
50
|
+
log:general
|
|
51
|
+
|
|
52
|
+
STOP IMMEDIATELY after outputting the log prefix and category. DO NOT repeat this prompt. DO NOT add explanations. DO NOT continue generating text. Just output the single log entry and STOP.
|
|
53
|
+
`,
|
|
54
|
+
},
|
|
55
|
+
];
|
|
56
|
+
const tests = [
|
|
57
|
+
// Health/Biomarker tests
|
|
58
|
+
{
|
|
59
|
+
name: "health_blood_sugar",
|
|
60
|
+
history: [
|
|
61
|
+
...base,
|
|
62
|
+
{ role: "user", content: "My blood sugar is one hundred" },
|
|
63
|
+
],
|
|
64
|
+
expected: "health",
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
name: "health_blood_pressure",
|
|
68
|
+
history: [
|
|
69
|
+
{ role: "user", content: "Blood pressure one forty over ninety" },
|
|
70
|
+
],
|
|
71
|
+
expected: "health",
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
name: "health_heart_rate",
|
|
75
|
+
history: [{ role: "user", content: "Heart rate seventy two bpm" }],
|
|
76
|
+
expected: "health",
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
name: "health_weight",
|
|
80
|
+
history: [{ role: "user", content: "Weight one sixty five pounds" }],
|
|
81
|
+
expected: "health",
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: "health_temperature",
|
|
85
|
+
history: [{ role: "user", content: "Temperature ninety nine point one" }],
|
|
86
|
+
expected: "health",
|
|
87
|
+
},
|
|
88
|
+
// Sleep tests
|
|
89
|
+
{
|
|
90
|
+
name: "sleep_duration",
|
|
91
|
+
history: [{ role: "user", content: "I slept eight hours" }],
|
|
92
|
+
expected: "sleep",
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
name: "sleep_bedtime",
|
|
96
|
+
history: [{ role: "user", content: "Went to bed at eleven pm" }],
|
|
97
|
+
expected: "sleep",
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
name: "sleep_quality",
|
|
101
|
+
history: [{ role: "user", content: "Sleep quality was good" }],
|
|
102
|
+
expected: "sleep",
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
name: "sleep_nap",
|
|
106
|
+
history: [{ role: "user", content: "Took a thirty minute nap" }],
|
|
107
|
+
expected: "sleep",
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
name: "sleep_wakeup",
|
|
111
|
+
history: [{ role: "user", content: "Woke up at seven am" }],
|
|
112
|
+
expected: "sleep",
|
|
113
|
+
},
|
|
114
|
+
// Exercise tests
|
|
115
|
+
{
|
|
116
|
+
name: "exercise_run",
|
|
117
|
+
history: [{ role: "user", content: "Went for a five mile run" }],
|
|
118
|
+
expected: "exercise",
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
name: "exercise_gym",
|
|
122
|
+
history: [{ role: "user", content: "Did a workout at the gym" }],
|
|
123
|
+
expected: "exercise",
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
name: "exercise_yoga",
|
|
127
|
+
history: [{ role: "user", content: "Did thirty minutes of yoga" }],
|
|
128
|
+
expected: "exercise",
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
name: "exercise_weights",
|
|
132
|
+
history: [{ role: "user", content: "Lifted weights for forty minutes" }],
|
|
133
|
+
expected: "exercise",
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
name: "exercise_tennis",
|
|
137
|
+
history: [{ role: "user", content: "Played tennis for two hours" }],
|
|
138
|
+
expected: "exercise",
|
|
139
|
+
},
|
|
140
|
+
// Wellness tests
|
|
141
|
+
{
|
|
142
|
+
name: "wellness_stress",
|
|
143
|
+
history: [{ role: "user", content: "I'm feeling stressed today" }],
|
|
144
|
+
expected: "wellness",
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
name: "wellness_mood",
|
|
148
|
+
history: [{ role: "user", content: "Mood is really good" }],
|
|
149
|
+
expected: "wellness",
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
name: "wellness_energy",
|
|
153
|
+
history: [{ role: "user", content: "Energy level is low" }],
|
|
154
|
+
expected: "wellness",
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
name: "wellness_anxiety",
|
|
158
|
+
history: [{ role: "user", content: "Anxiety level is high" }],
|
|
159
|
+
expected: "wellness",
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
name: "wellness_recovery",
|
|
163
|
+
history: [{ role: "user", content: "Recovery score is eighty five" }],
|
|
164
|
+
expected: "wellness",
|
|
165
|
+
},
|
|
166
|
+
// Steps tests
|
|
167
|
+
{
|
|
168
|
+
name: "steps_count",
|
|
169
|
+
history: [{ role: "user", content: "I did ten thousand steps today" }],
|
|
170
|
+
expected: "steps",
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
name: "steps_walking",
|
|
174
|
+
history: [{ role: "user", content: "Walked for forty five minutes" }],
|
|
175
|
+
expected: "steps",
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
name: "steps_goal",
|
|
179
|
+
history: [{ role: "user", content: "Reached my step goal" }],
|
|
180
|
+
expected: "steps",
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
name: "steps_low",
|
|
184
|
+
history: [{ role: "user", content: "Only walked three thousand steps" }],
|
|
185
|
+
expected: "steps",
|
|
186
|
+
},
|
|
187
|
+
// Meal tests
|
|
188
|
+
{
|
|
189
|
+
name: "meal_breakfast",
|
|
190
|
+
history: [{ role: "user", content: "Had scrambled eggs for breakfast" }],
|
|
191
|
+
expected: "meal",
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
name: "meal_lunch",
|
|
195
|
+
history: [{ role: "user", content: "Ate a turkey sandwich for lunch" }],
|
|
196
|
+
expected: "meal",
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
name: "meal_dinner",
|
|
200
|
+
history: [
|
|
201
|
+
{ role: "user", content: "Had a two fifty g steak with veggies" },
|
|
202
|
+
],
|
|
203
|
+
expected: "meal",
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
name: "meal_snack",
|
|
207
|
+
history: [{ role: "user", content: "Snacked on an apple" }],
|
|
208
|
+
expected: "meal",
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
name: "meal_drink",
|
|
212
|
+
history: [{ role: "user", content: "Drank a protein shake" }],
|
|
213
|
+
expected: "meal",
|
|
214
|
+
},
|
|
215
|
+
// General tests
|
|
216
|
+
{
|
|
217
|
+
name: "general_question",
|
|
218
|
+
history: [{ role: "user", content: "How are you doing?" }],
|
|
219
|
+
expected: "general",
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
name: "general_weather",
|
|
223
|
+
history: [{ role: "user", content: "What's the weather like?" }],
|
|
224
|
+
expected: "general",
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
name: "general_help",
|
|
228
|
+
history: [{ role: "user", content: "Can you help me with something?" }],
|
|
229
|
+
expected: "general",
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
name: "general_explanation",
|
|
233
|
+
history: [{ role: "user", content: "Explain how this works" }],
|
|
234
|
+
expected: "general",
|
|
235
|
+
},
|
|
236
|
+
// Edge cases
|
|
237
|
+
{
|
|
238
|
+
name: "edge_mixed_health_meal",
|
|
239
|
+
history: [{ role: "user", content: "Ate lunch and blood sugar went up" }],
|
|
240
|
+
expected: "health", // Should prioritize the health metric
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
name: "edge_exercise_steps",
|
|
244
|
+
history: [
|
|
245
|
+
{ role: "user", content: "Ran and got fifteen thousand steps" },
|
|
246
|
+
],
|
|
247
|
+
expected: "steps", // Should prioritize the more specific exercise
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
name: "edge_tired_after_workout",
|
|
251
|
+
history: [{ role: "user", content: "Feeling tired after gym session" }],
|
|
252
|
+
expected: "wellness", // Should focus on the feeling/wellness aspect
|
|
253
|
+
},
|
|
254
|
+
];
|
|
255
|
+
const results = [];
|
|
256
|
+
let totalSuccesses = 0;
|
|
257
|
+
let totalFailures = 0;
|
|
258
|
+
for (const test of tests) {
|
|
259
|
+
const startTime = performance.now();
|
|
260
|
+
const buffer = [];
|
|
261
|
+
let tokenCount = 0;
|
|
262
|
+
let firstTokenTime = null;
|
|
263
|
+
const result = completion({ modelId, history: test.history, stream: true });
|
|
264
|
+
for await (const token of result.tokenStream) {
|
|
265
|
+
if (firstTokenTime === null) {
|
|
266
|
+
firstTokenTime = performance.now();
|
|
267
|
+
}
|
|
268
|
+
buffer.push(token);
|
|
269
|
+
tokenCount++;
|
|
270
|
+
const currentOutput = buffer.join("");
|
|
271
|
+
// Stop if we have a complete log entry (log: + word)
|
|
272
|
+
if (currentOutput.match(/log:\w+/i)) {
|
|
273
|
+
// Add a few more tokens to ensure completion, then stop
|
|
274
|
+
if (tokenCount > currentOutput.indexOf("log:") + 10) {
|
|
275
|
+
break;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
// Emergency stops to prevent runaway generation
|
|
279
|
+
if (tokenCount > 100 ||
|
|
280
|
+
currentOutput.includes("Output exactly one word") ||
|
|
281
|
+
currentOutput.includes("Choose from:") ||
|
|
282
|
+
currentOutput.includes("Examples:") ||
|
|
283
|
+
currentOutput.length > 500) {
|
|
284
|
+
console.log(`ā ļø Stopped runaway generation for ${test.name} after ${tokenCount} tokens`);
|
|
285
|
+
break;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
// Get the stats from the completion stream
|
|
289
|
+
const stats = await result.stats;
|
|
290
|
+
console.log(`š Stats for ${test.name}:`, stats);
|
|
291
|
+
const endTime = performance.now();
|
|
292
|
+
const totalTime = endTime - startTime;
|
|
293
|
+
const ttft = firstTokenTime ? firstTokenTime - startTime : 0; // Time to First Token
|
|
294
|
+
const tokensPerSecond = tokenCount > 0
|
|
295
|
+
? tokenCount / ((endTime - (firstTokenTime || startTime)) / 1000)
|
|
296
|
+
: 0;
|
|
297
|
+
const fullOutput = buffer.join("");
|
|
298
|
+
// Look for log: prefix in the output
|
|
299
|
+
const logMatch = fullOutput.match(/log:(\w+)/i);
|
|
300
|
+
const actual = logMatch?.[1]?.toLowerCase() || "";
|
|
301
|
+
const success = actual === test.expected;
|
|
302
|
+
if (success) {
|
|
303
|
+
console.log(`ā
${test.name} (${totalTime.toFixed(0)}ms, ${tokenCount} tokens, ${tokensPerSecond.toFixed(1)} tok/s)`);
|
|
304
|
+
totalSuccesses++;
|
|
305
|
+
}
|
|
306
|
+
else {
|
|
307
|
+
console.log(`ā ${test.name} (${totalTime.toFixed(0)}ms, ${tokenCount} tokens, ${tokensPerSecond.toFixed(1)} tok/s)`);
|
|
308
|
+
totalFailures++;
|
|
309
|
+
}
|
|
310
|
+
results.push({
|
|
311
|
+
name: test.name,
|
|
312
|
+
input: test.history[test.history.length - 1]?.content ?? "no input",
|
|
313
|
+
expected: test.expected,
|
|
314
|
+
actual,
|
|
315
|
+
success,
|
|
316
|
+
fullOutput: fullOutput.replace(/\n/g, "\\n"),
|
|
317
|
+
timing: {
|
|
318
|
+
totalTime: Math.round(totalTime),
|
|
319
|
+
ttft: Math.round(ttft),
|
|
320
|
+
tokenCount,
|
|
321
|
+
tokensPerSecond: Math.round(tokensPerSecond * 10) / 10,
|
|
322
|
+
},
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
// Print detailed results
|
|
326
|
+
console.log("\n" + "=".repeat(80));
|
|
327
|
+
console.log("DETAILED TEST RESULTS");
|
|
328
|
+
console.log("=".repeat(80));
|
|
329
|
+
for (const result of results) {
|
|
330
|
+
console.log(`\nTest: ${result.name}`);
|
|
331
|
+
console.log(`Input: "${result.input}"`);
|
|
332
|
+
console.log(`Expected: "${result.expected}"`);
|
|
333
|
+
console.log(`Got: "${result.actual}"`);
|
|
334
|
+
console.log(`Status: ${result.success ? "ā
PASS" : "ā FAIL"}`);
|
|
335
|
+
console.log(`Timing: ${result.timing.totalTime}ms total, TTFT: ${result.timing.ttft}ms, ${result.timing.tokenCount} tokens, ${result.timing.tokensPerSecond} tok/s`);
|
|
336
|
+
if (!result.success) {
|
|
337
|
+
console.log(`Full Output: "${result.fullOutput}"`);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
console.log("\n" + "=".repeat(80));
|
|
341
|
+
console.log(`SUMMARY: ${totalSuccesses}/${results.length} tests passed (${Math.round((totalSuccesses / results.length) * 100)}%)`);
|
|
342
|
+
console.log(`Successes: ${totalSuccesses}`);
|
|
343
|
+
console.log(`Failures: ${totalFailures}`);
|
|
344
|
+
// Calculate timing statistics
|
|
345
|
+
const timings = results.map((r) => r.timing);
|
|
346
|
+
const avgTotalTime = timings.reduce((sum, t) => sum + t.totalTime, 0) / timings.length;
|
|
347
|
+
const avgTTFT = timings.reduce((sum, t) => sum + t.ttft, 0) / timings.length;
|
|
348
|
+
const avgTokens = timings.reduce((sum, t) => sum + t.tokenCount, 0) / timings.length;
|
|
349
|
+
const avgTPS = timings.reduce((sum, t) => sum + t.tokensPerSecond, 0) / timings.length;
|
|
350
|
+
const totalTime = timings.reduce((sum, t) => sum + t.totalTime, 0);
|
|
351
|
+
console.log(`\nTIMING STATS:`);
|
|
352
|
+
console.log(`Total Test Time: ${(totalTime / 1000).toFixed(1)}s`);
|
|
353
|
+
console.log(`Average per test: ${avgTotalTime.toFixed(0)}ms`);
|
|
354
|
+
console.log(`Average TTFT: ${avgTTFT.toFixed(0)}ms`);
|
|
355
|
+
console.log(`Average tokens: ${avgTokens.toFixed(1)}`);
|
|
356
|
+
console.log(`Average speed: ${avgTPS.toFixed(1)} tok/s`);
|
|
357
|
+
console.log("=".repeat(80));
|
|
358
|
+
await unloadModel({ modelId, clearStorage: false });
|
|
359
|
+
process.exit(0);
|
|
360
|
+
}
|
|
361
|
+
catch (error) {
|
|
362
|
+
console.error("ā Error:", error);
|
|
363
|
+
process.exit(1);
|
|
364
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { completion, loadModel, QWEN_3_1_7B_INST_Q4, unloadModel, } from "@qvac/sdk";
|
|
2
|
+
// Simple tool execution
|
|
3
|
+
function executeTool(toolName, params) {
|
|
4
|
+
if (toolName === "calculate") {
|
|
5
|
+
const match = params.match(/a:(\d+),\s*b:(\d+),\s*op:([+\-*/])/);
|
|
6
|
+
if (match) {
|
|
7
|
+
const [, a, b, op] = match;
|
|
8
|
+
const result = op === "+"
|
|
9
|
+
? +a + +b
|
|
10
|
+
: op === "-"
|
|
11
|
+
? +a - +b
|
|
12
|
+
: op === "*"
|
|
13
|
+
? +a * +b
|
|
14
|
+
: +a / +b;
|
|
15
|
+
return `${result}`;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
if (toolName === "get_time") {
|
|
19
|
+
return new Date().toLocaleString();
|
|
20
|
+
}
|
|
21
|
+
return "Tool not found";
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
console.log("š Loading MedGemma...");
|
|
25
|
+
const modelId = await loadModel({
|
|
26
|
+
modelSrc: QWEN_3_1_7B_INST_Q4,
|
|
27
|
+
modelType: "llm",
|
|
28
|
+
modelConfig: {
|
|
29
|
+
ctx_size: 2048,
|
|
30
|
+
},
|
|
31
|
+
onProgress: (progress) => console.log(`${progress.percentage.toFixed(1)}%`),
|
|
32
|
+
});
|
|
33
|
+
const systemPrompt = `You are a helpful assistant. When you need to use tools, use this XML format:
|
|
34
|
+
|
|
35
|
+
<tool_call>
|
|
36
|
+
<tool_name>calculate</tool_name>
|
|
37
|
+
<parameters>a:15, b:24, op:*</parameters>
|
|
38
|
+
</tool_call>
|
|
39
|
+
|
|
40
|
+
<tool_call>
|
|
41
|
+
<tool_name>get_time</tool_name>
|
|
42
|
+
<parameters></parameters>
|
|
43
|
+
</tool_call>
|
|
44
|
+
|
|
45
|
+
Available tools:
|
|
46
|
+
- calculate: needs a (number), b (number), op (+, -, *, /)
|
|
47
|
+
- get_time: no parameters needed`;
|
|
48
|
+
const conversation = [
|
|
49
|
+
{ role: "system", content: systemPrompt },
|
|
50
|
+
{ role: "user", content: "What's 30 * 5? Also what time is it?" },
|
|
51
|
+
];
|
|
52
|
+
console.log("\nš¤ Response:");
|
|
53
|
+
let response = "";
|
|
54
|
+
const result = completion({ modelId, history: conversation, stream: true });
|
|
55
|
+
for await (const token of result.tokenStream) {
|
|
56
|
+
process.stdout.write(token);
|
|
57
|
+
response += token;
|
|
58
|
+
}
|
|
59
|
+
const stats = await result.stats;
|
|
60
|
+
console.log("\nš Performance Stats:", stats);
|
|
61
|
+
// Parse XML tool calls
|
|
62
|
+
const toolRegex = /<tool_call>\s*<tool_name>([^<]+)<\/tool_name>\s*<parameters>([^<]*)<\/parameters>\s*<\/tool_call>/g;
|
|
63
|
+
let match;
|
|
64
|
+
const hasTools = toolRegex.test(response);
|
|
65
|
+
if (hasTools) {
|
|
66
|
+
console.log("\n\nš§ Executing tools:");
|
|
67
|
+
toolRegex.lastIndex = 0; // Reset regex
|
|
68
|
+
while ((match = toolRegex.exec(response)) !== null) {
|
|
69
|
+
const [, toolName, params] = match;
|
|
70
|
+
console.log(`⤠${toolName}(${params})`);
|
|
71
|
+
console.log(`ā
${executeTool(toolName, params)}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
console.log("\n\nš«” Done!");
|
|
75
|
+
await unloadModel({ modelId, clearStorage: false });
|
|
76
|
+
process.exit(0);
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
console.error("ā Error:", error);
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { completion, LLAMA_3_2_1B_INST_Q4_0, loadModel, QWEN_3_1_7B_INST_Q4, unloadModel, } from "@qvac/sdk";
|
|
2
|
+
try {
|
|
3
|
+
const alice = await loadModel({
|
|
4
|
+
modelSrc: QWEN_3_1_7B_INST_Q4,
|
|
5
|
+
modelType: "llm",
|
|
6
|
+
modelConfig: {
|
|
7
|
+
ctx_size: 4096,
|
|
8
|
+
},
|
|
9
|
+
});
|
|
10
|
+
const bob = await loadModel({
|
|
11
|
+
modelSrc: LLAMA_3_2_1B_INST_Q4_0,
|
|
12
|
+
modelType: "llm",
|
|
13
|
+
modelConfig: {
|
|
14
|
+
ctx_size: 4096,
|
|
15
|
+
},
|
|
16
|
+
onProgress: (progress) => console.log(`Loading Bob: ${progress.percentage.toFixed(1)}%`),
|
|
17
|
+
});
|
|
18
|
+
const aliceHistory = [
|
|
19
|
+
{
|
|
20
|
+
role: "system",
|
|
21
|
+
content: "You answer questions about.",
|
|
22
|
+
},
|
|
23
|
+
{ role: "user", content: "What is Bitcoin?" },
|
|
24
|
+
];
|
|
25
|
+
const bobHistory = [
|
|
26
|
+
{
|
|
27
|
+
role: "system",
|
|
28
|
+
content: "You ask questions about Bitcoin in one sentence.",
|
|
29
|
+
},
|
|
30
|
+
];
|
|
31
|
+
console.log("šš»āāļø Bob: ", "What is Bitcoin?");
|
|
32
|
+
const aliceResponse = completion({
|
|
33
|
+
modelId: alice,
|
|
34
|
+
history: [...aliceHistory],
|
|
35
|
+
stream: false,
|
|
36
|
+
});
|
|
37
|
+
const aliceText = await aliceResponse.text;
|
|
38
|
+
aliceHistory.push({ role: "assistant", content: aliceText });
|
|
39
|
+
console.log("šš»āāļø Alice: ", aliceText);
|
|
40
|
+
console.log("š Alice Stats: ", await aliceResponse.stats);
|
|
41
|
+
const bobResponse = completion({
|
|
42
|
+
modelId: bob,
|
|
43
|
+
history: [...bobHistory, { role: "user", content: aliceText }],
|
|
44
|
+
stream: false,
|
|
45
|
+
});
|
|
46
|
+
const bobText = await bobResponse.text;
|
|
47
|
+
bobHistory.push({ role: "assistant", content: bobText });
|
|
48
|
+
console.log("šš»āāļø Bob: ", bobText);
|
|
49
|
+
console.log("š Bob Stats: ", await bobResponse.stats);
|
|
50
|
+
const aliceResponse2 = completion({
|
|
51
|
+
modelId: alice,
|
|
52
|
+
history: [...aliceHistory, { role: "user", content: bobText }],
|
|
53
|
+
stream: false,
|
|
54
|
+
});
|
|
55
|
+
const aliceText2 = await aliceResponse2.text;
|
|
56
|
+
aliceHistory.push({ role: "assistant", content: aliceText2 });
|
|
57
|
+
console.log("šš»āāļø Alice: ", aliceText2);
|
|
58
|
+
console.log("š Alice Stats: ", await aliceResponse2.stats);
|
|
59
|
+
const bobResponse2 = completion({
|
|
60
|
+
modelId: bob,
|
|
61
|
+
history: [...bobHistory, { role: "user", content: aliceText2 }],
|
|
62
|
+
stream: false,
|
|
63
|
+
});
|
|
64
|
+
const bobText2 = await bobResponse2.text;
|
|
65
|
+
bobHistory.push({ role: "assistant", content: bobText2 });
|
|
66
|
+
console.log("šš»āāļø Bob: ", bobText2);
|
|
67
|
+
console.log("š Bob Stats: ", await bobResponse2.stats);
|
|
68
|
+
await unloadModel({ modelId: alice, clearStorage: false });
|
|
69
|
+
await unloadModel({ modelId: bob, clearStorage: false });
|
|
70
|
+
process.exit(0);
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
console.error("ā Error:", error);
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { LLAMA_3_2_1B_INST_Q4_0, downloadAsset, WHISPER_LARGE_3, } from "@qvac/sdk";
|
|
2
|
+
try {
|
|
3
|
+
const llamaDownloadPromise = downloadAsset({
|
|
4
|
+
assetSrc: LLAMA_3_2_1B_INST_Q4_0,
|
|
5
|
+
onProgress: (progress) => {
|
|
6
|
+
console.log("š¬ Llama progress:", progress);
|
|
7
|
+
},
|
|
8
|
+
});
|
|
9
|
+
const whisperDownloadPromise = downloadAsset({
|
|
10
|
+
assetSrc: WHISPER_LARGE_3,
|
|
11
|
+
onProgress: (progress) => {
|
|
12
|
+
console.log("š Whisper progress:", progress);
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
await Promise.all([llamaDownloadPromise, whisperDownloadPromise]);
|
|
16
|
+
process.exit(0);
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
console.error("ā Error:", error);
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
// example-chroma.ts
|
|
2
|
+
import { embed, loadModel, unloadModel, GTE_LARGE_FP16 } from "@qvac/sdk";
|
|
3
|
+
import { ChromaClient } from "chromadb";
|
|
4
|
+
// Setup instructions for ChromaDB server
|
|
5
|
+
const CHROMADB_SETUP_INSTRUCTIONS = `
|
|
6
|
+
š To run this example, you need a ChromaDB server running locally.
|
|
7
|
+
|
|
8
|
+
Setup options:
|
|
9
|
+
|
|
10
|
+
1. Using Chroma CLI (recommended):
|
|
11
|
+
pip install chromadb
|
|
12
|
+
chroma run --host localhost --port 8000 --path ./my_chroma_data
|
|
13
|
+
|
|
14
|
+
2. Using Docker:
|
|
15
|
+
docker pull chromadb/chroma
|
|
16
|
+
docker run -p 8000:8000 chromadb/chroma
|
|
17
|
+
|
|
18
|
+
For more details, visit: https://docs.trychroma.com/docs/overview/getting-started?lang=typescript
|
|
19
|
+
`;
|
|
20
|
+
async function initializeChromaClient() {
|
|
21
|
+
const client = new ChromaClient({ host: "localhost", port: 8000 });
|
|
22
|
+
try {
|
|
23
|
+
await client.heartbeat();
|
|
24
|
+
console.log("ā
Connected to ChromaDB server");
|
|
25
|
+
return client;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
console.error("ā Failed to connect to ChromaDB server");
|
|
29
|
+
console.error("Please ensure the server is running on localhost:8000");
|
|
30
|
+
console.error(CHROMADB_SETUP_INSTRUCTIONS);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
// Get query from command line or use default
|
|
36
|
+
const query = process.argv[2] || "machine learning algorithms";
|
|
37
|
+
console.log(`š Query: "${query}"`);
|
|
38
|
+
const client = await initializeChromaClient();
|
|
39
|
+
const modelId = await loadModel({
|
|
40
|
+
modelSrc: GTE_LARGE_FP16,
|
|
41
|
+
modelType: "embeddings",
|
|
42
|
+
onProgress: (p) => console.log(`Loading model... ${Math.round(p.percentage)}%`),
|
|
43
|
+
});
|
|
44
|
+
// Sample corpus
|
|
45
|
+
const samples = [
|
|
46
|
+
{
|
|
47
|
+
id: 1,
|
|
48
|
+
text: "Machine learning is a subset of artificial intelligence that focuses on algorithms that can learn and make predictions from data without being explicitly programmed for every task.",
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
id: 2,
|
|
52
|
+
text: "Deep learning uses neural networks with multiple layers to process and learn from complex data patterns, enabling breakthroughs in image recognition and natural language processing.",
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
id: 3,
|
|
56
|
+
text: "Natural language processing combines computational linguistics with machine learning to help computers understand, interpret, and generate human language in a meaningful way.",
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
id: 4,
|
|
60
|
+
text: "Computer vision enables machines to interpret and understand visual information from the world, using techniques like image classification, object detection, and facial recognition.",
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
id: 5,
|
|
64
|
+
text: "Quantum computing leverages quantum mechanical phenomena to process information in fundamentally different ways than classical computers, potentially solving certain problems exponentially faster.",
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: 6,
|
|
68
|
+
text: "Blockchain technology creates decentralized, immutable ledgers that enable secure peer-to-peer transactions without requiring a central authority or intermediary.",
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
id: 7,
|
|
72
|
+
text: "Cloud computing delivers computing services over the internet, allowing users to access resources like storage, processing power, and applications on-demand from anywhere.",
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
id: 8,
|
|
76
|
+
text: "Cybersecurity protects digital systems, networks, and data from malicious attacks, unauthorized access, and various forms of cyber threats through multiple layers of defense.",
|
|
77
|
+
},
|
|
78
|
+
];
|
|
79
|
+
// (Re)create the collection
|
|
80
|
+
const collectionName = "documents";
|
|
81
|
+
try {
|
|
82
|
+
await client.deleteCollection({ name: collectionName });
|
|
83
|
+
}
|
|
84
|
+
catch (e) {
|
|
85
|
+
console.warn(`Collection didn't exist, no need to delete: ${String(e)}`);
|
|
86
|
+
}
|
|
87
|
+
const collection = await client.createCollection({
|
|
88
|
+
name: collectionName,
|
|
89
|
+
embeddingFunction: null,
|
|
90
|
+
});
|
|
91
|
+
// Embed and add documents (we're bringing our own embeddings)
|
|
92
|
+
console.log("š Embedding documents...");
|
|
93
|
+
const ids = [];
|
|
94
|
+
const documents = [];
|
|
95
|
+
const embeddings = [];
|
|
96
|
+
for (const s of samples) {
|
|
97
|
+
ids.push(String(s.id));
|
|
98
|
+
documents.push(s.text);
|
|
99
|
+
embeddings.push(await embed({ modelId, text: s.text }));
|
|
100
|
+
}
|
|
101
|
+
await collection.add({
|
|
102
|
+
ids,
|
|
103
|
+
documents,
|
|
104
|
+
embeddings,
|
|
105
|
+
});
|
|
106
|
+
console.log("š Searching for similar documents...");
|
|
107
|
+
const queryEmbedding = await embed({ modelId, text: query });
|
|
108
|
+
// Query top 3 by vector similarity and include distances
|
|
109
|
+
const res = await collection.query({
|
|
110
|
+
queryEmbeddings: [queryEmbedding],
|
|
111
|
+
nResults: 3,
|
|
112
|
+
include: ["documents", "distances"],
|
|
113
|
+
});
|
|
114
|
+
console.log("\nš Top 3 most similar documents:");
|
|
115
|
+
const docs = res.documents?.[0] ?? [];
|
|
116
|
+
const dists = res.distances?.[0] ?? [];
|
|
117
|
+
for (let i = 0; i < docs.length; i++) {
|
|
118
|
+
console.log("=".repeat(50) + " Top result:");
|
|
119
|
+
console.log(`\n${i + 1}. (Score: ${dists[i]?.toFixed(4)})`);
|
|
120
|
+
console.log(` ${docs[i]}`);
|
|
121
|
+
console.log("=".repeat(100));
|
|
122
|
+
console.log();
|
|
123
|
+
}
|
|
124
|
+
await unloadModel({ modelId });
|
|
125
|
+
process.exit(0);
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
console.error("ā Error:", error);
|
|
129
|
+
process.exit(1);
|
|
130
|
+
}
|