@qvac/sdk 0.3.0 → 0.4.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/README.md +22 -0
- package/dist/client/api/cancel.d.ts +1 -1
- package/dist/client/api/cancel.js +4 -3
- package/dist/client/api/completion-stream.d.ts +24 -32
- package/dist/client/api/completion-stream.js +142 -50
- package/dist/client/api/delete-cache.js +3 -2
- package/dist/client/api/download-asset.d.ts +3 -3
- package/dist/client/api/download-asset.js +12 -17
- package/dist/client/api/embed.d.ts +1 -1
- package/dist/client/api/embed.js +4 -3
- package/dist/client/api/get-model-info.d.ts +29 -0
- package/dist/client/api/get-model-info.js +14 -0
- package/dist/client/api/index.d.ts +3 -0
- package/dist/client/api/index.js +3 -0
- package/dist/client/api/load-model.d.ts +3 -3
- package/dist/client/api/load-model.js +13 -22
- package/dist/client/api/logging-stream.d.ts +1 -1
- package/dist/client/api/logging-stream.js +3 -2
- package/dist/client/api/ping.d.ts +1 -1
- package/dist/client/api/ping.js +3 -2
- package/dist/client/api/provide.d.ts +1 -1
- package/dist/client/api/provide.js +4 -3
- package/dist/client/api/rag.d.ts +3 -3
- package/dist/client/api/rag.js +13 -12
- package/dist/client/api/set-config.d.ts +7 -0
- package/dist/client/api/set-config.js +20 -0
- package/dist/client/api/stop-provider.d.ts +1 -1
- package/dist/client/api/stop-provider.js +4 -3
- package/dist/client/api/text-to-speech.d.ts +7 -0
- package/dist/client/api/text-to-speech.js +58 -0
- package/dist/client/api/transcribe.d.ts +4 -2
- package/dist/client/api/transcribe.js +9 -5
- package/dist/client/api/translate.d.ts +1 -1
- package/dist/client/api/translate.js +3 -2
- package/dist/client/api/unload-model.d.ts +5 -1
- package/dist/client/api/unload-model.js +14 -4
- package/dist/client/config-manager.d.ts +4 -0
- package/dist/client/config-manager.js +8 -0
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/init-hooks.d.ts +6 -0
- package/dist/client/init-hooks.js +37 -0
- package/dist/client/rpc/bare-client.d.ts +69 -0
- package/dist/client/rpc/bare-client.js +5 -4
- package/dist/client/rpc/bare-rpc-client.js +7 -3
- package/dist/client/rpc/expo-rpc-client.d.ts +1 -0
- package/dist/client/rpc/expo-rpc-client.js +9 -1
- package/dist/client/rpc/node-rpc-client.d.ts +1 -1
- package/dist/client/rpc/node-rpc-client.js +22 -9
- package/dist/client/rpc/rpc-client.d.ts +1 -0
- package/dist/client/rpc/rpc-client.js +20 -1
- package/dist/constants/audio.d.ts +1 -2
- package/dist/constants/audio.js +1 -17
- package/dist/examples/cache-management.d.ts +2 -0
- package/dist/examples/cache-management.js +97 -0
- package/dist/examples/delegated-inference/consumer.js +2 -2
- package/dist/examples/download-with-blind-relays.d.ts +2 -0
- package/dist/examples/download-with-blind-relays.js +48 -0
- package/dist/examples/download-with-cancel.js +3 -4
- package/dist/examples/embed-hyperdrive.js +0 -1
- package/dist/examples/kv-cache-cleanup.js +0 -1
- package/dist/examples/kv-cache-custom-key.js +0 -1
- package/dist/examples/kv-cache-example.js +0 -1
- package/dist/examples/llamacpp-file-logging.js +0 -1
- package/dist/examples/llamacpp-filesystem.js +2 -2
- package/dist/examples/llamacpp-http.js +0 -1
- package/dist/examples/llamacpp-hyperdrive.js +0 -1
- package/dist/examples/llamacpp-multimodal.js +0 -1
- package/dist/examples/llamacpp-native-tools.js +118 -36
- package/dist/examples/llamacpp-sharded.d.ts +2 -0
- package/dist/examples/llamacpp-sharded.js +44 -0
- package/dist/examples/multi-model-demo.js +0 -1
- package/dist/examples/parallel-download.js +2 -2
- package/dist/examples/rag/rag-chromadb.js +0 -1
- package/dist/examples/rag/rag-hyperdb-workspaces.js +0 -1
- package/dist/examples/rag/rag-hyperdb.js +0 -1
- package/dist/examples/rag/rag-lancedb.js +0 -1
- package/dist/examples/rag/rag-sqlite.js +0 -1
- package/dist/examples/text-to-speech.d.ts +3 -0
- package/dist/examples/text-to-speech.js +137 -0
- package/dist/examples/translation/translation-indic.js +3 -1
- package/dist/examples/translation/translation-llm-context.js +0 -1
- package/dist/examples/translation/translation-llm.js +2 -2
- package/dist/examples/translation/translation-opus.js +3 -1
- package/dist/examples/translation/translation-stream.js +0 -1
- package/dist/examples/whispercpp-filesystem.js +32 -5
- package/dist/examples/whispercpp-microphone-record.js +9 -9
- package/dist/examples/whispercpp-prompt.d.ts +2 -0
- package/dist/examples/whispercpp-prompt.js +68 -0
- package/dist/expo/plugins/withMobileBundle.js +9 -3
- package/dist/index.d.ts +4 -2
- package/dist/index.js +4 -2
- package/dist/models/hyperdrive/models.d.ts +1916 -100
- package/dist/models/hyperdrive/models.js +2042 -102
- package/dist/schemas/common.d.ts +413 -58
- package/dist/schemas/common.js +9 -0
- package/dist/schemas/completion-stream.d.ts +26 -22
- package/dist/schemas/completion-stream.js +9 -23
- package/dist/schemas/download-asset.d.ts +77 -2
- package/dist/schemas/download-asset.js +15 -4
- package/dist/schemas/get-model-info.d.ts +100 -0
- package/dist/schemas/get-model-info.js +40 -0
- package/dist/schemas/index.d.ts +7 -0
- package/dist/schemas/index.js +7 -0
- package/dist/schemas/llamacpp-config.d.ts +2 -1
- package/dist/schemas/llamacpp-config.js +3 -4
- package/dist/schemas/load-model.d.ts +2316 -266
- package/dist/schemas/load-model.js +157 -10
- package/dist/schemas/model-src-utils.d.ts +98 -0
- package/dist/schemas/model-src-utils.js +31 -0
- package/dist/schemas/sdk-errors-client.d.ts +25 -0
- package/dist/schemas/sdk-errors-client.js +111 -0
- package/dist/schemas/sdk-errors-server.d.ts +55 -0
- package/dist/schemas/sdk-errors-server.js +271 -0
- package/dist/schemas/set-config.d.ts +21 -0
- package/dist/schemas/set-config.js +14 -0
- package/dist/schemas/text-to-speech.d.ts +34 -0
- package/dist/schemas/text-to-speech.js +25 -0
- package/dist/schemas/tools.d.ts +62 -0
- package/dist/schemas/tools.js +43 -0
- package/dist/schemas/transcription.d.ts +25 -2
- package/dist/schemas/transcription.js +12 -1
- package/dist/schemas/translation-config.d.ts +33 -5
- package/dist/schemas/translation-config.js +18 -1
- package/dist/schemas/unload-model.d.ts +2 -0
- package/dist/schemas/unload-model.js +2 -0
- package/dist/schemas/whispercpp-config.d.ts +55 -18
- package/dist/schemas/whispercpp-config.js +63 -15
- package/dist/server/bare/addons/cancel.js +2 -1
- package/dist/server/bare/addons/llamacpp/create-model.d.ts +9 -2
- package/dist/server/bare/addons/llamacpp/create-model.js +23 -23
- package/dist/server/bare/addons/llamacpp/handlers/completion-stream.d.ts +10 -2
- package/dist/server/bare/addons/llamacpp/handlers/completion-stream.js +62 -43
- package/dist/server/bare/addons/llamacpp/handlers/embed.js +3 -2
- package/dist/server/bare/addons/llamacpp/kv-cache-utils.d.ts +1 -1
- package/dist/server/bare/addons/llamacpp/kv-cache-utils.js +6 -2
- package/dist/server/bare/addons/load-model.js +59 -28
- package/dist/server/bare/addons/translation/create-model.d.ts +5 -1
- package/dist/server/bare/addons/translation/create-model.js +17 -25
- package/dist/server/bare/addons/translation/handlers/translate.js +10 -1
- package/dist/server/bare/addons/tts/create-model.d.ts +10 -0
- package/dist/server/bare/addons/tts/create-model.js +25 -0
- package/dist/server/bare/addons/tts/handlers/text-to-speech.d.ts +3 -0
- package/dist/server/bare/addons/tts/handlers/text-to-speech.js +87 -0
- package/dist/server/bare/addons/tts/index.d.ts +3 -0
- package/dist/server/bare/addons/tts/index.js +2 -0
- package/dist/server/bare/addons/unload-model.js +21 -3
- package/dist/server/bare/addons/whispercpp/create-model.d.ts +5 -1
- package/dist/server/bare/addons/whispercpp/create-model.js +13 -32
- package/dist/server/bare/addons/whispercpp/handlers/transcribe-stream.js +41 -20
- package/dist/server/bare/delegate-rpc-client.js +3 -2
- package/dist/server/bare/hyperswarm.d.ts +3 -0
- package/dist/server/bare/hyperswarm.js +22 -1
- package/dist/server/bare/rag-hyperdb/rag-manager.js +2 -3
- package/dist/server/bare/registry/config-registry.d.ts +5 -0
- package/dist/server/bare/registry/config-registry.js +39 -0
- package/dist/server/bare/registry/model-registry.d.ts +13 -0
- package/dist/server/bare/registry/model-registry.js +24 -7
- package/dist/server/rpc/handle-request.js +42 -3
- package/dist/server/rpc/handlers/completion-stream-delegated.js +2 -1
- package/dist/server/rpc/handlers/completion-stream.js +11 -4
- package/dist/server/rpc/handlers/download-asset.js +2 -3
- package/dist/server/rpc/handlers/get-model-info.d.ts +3 -0
- package/dist/server/rpc/handlers/get-model-info.js +148 -0
- package/dist/server/rpc/handlers/index.d.ts +4 -0
- package/dist/server/rpc/handlers/index.js +6 -0
- package/dist/server/rpc/handlers/load-model/http.js +51 -10
- package/dist/server/rpc/handlers/load-model/hyperdrive.js +336 -156
- package/dist/server/rpc/handlers/load-model/index.js +1 -1
- package/dist/server/rpc/handlers/load-model/resolve.d.ts +1 -1
- package/dist/server/rpc/handlers/load-model/resolve.js +10 -6
- package/dist/server/rpc/handlers/load-model-delegated.js +7 -4
- package/dist/server/rpc/handlers/load-model.js +19 -1
- package/dist/server/rpc/handlers/provideHandler/handler.js +2 -1
- package/dist/server/rpc/handlers/rag.js +0 -3
- package/dist/server/rpc/handlers/set-config.d.ts +3 -0
- package/dist/server/rpc/handlers/set-config.js +18 -0
- package/dist/server/rpc/handlers/stopProvideHandler.js +3 -1
- package/dist/server/rpc/handlers/text-to-speech.d.ts +3 -0
- package/dist/server/rpc/handlers/text-to-speech.js +7 -0
- package/dist/server/rpc/handlers/transcribe-stream.js +6 -2
- package/dist/server/rpc/handlers/unload-model.js +7 -0
- package/dist/server/utils/audio/decoder.js +1 -1
- package/dist/server/utils/cache.d.ts +13 -8
- package/dist/server/utils/cache.js +69 -14
- package/dist/server/utils/checksum.d.ts +2 -0
- package/dist/server/utils/checksum.js +24 -0
- package/dist/server/utils/index.d.ts +2 -0
- package/dist/server/utils/index.js +2 -0
- package/dist/server/utils/shard-utils.d.ts +22 -0
- package/dist/server/utils/shard-utils.js +37 -0
- package/dist/server/utils/tool-integration.d.ts +13 -0
- package/dist/server/utils/tool-integration.js +43 -0
- package/dist/server/utils/tool-parser.d.ts +7 -0
- package/dist/server/utils/tool-parser.js +244 -0
- package/dist/utils/errors-base.d.ts +3 -0
- package/dist/utils/errors-base.js +13 -0
- package/dist/utils/errors-client.d.ts +107 -0
- package/dist/utils/errors-client.js +186 -0
- package/dist/utils/errors-server.d.ts +146 -0
- package/dist/utils/errors-server.js +253 -0
- package/dist/utils/tool-helpers.d.ts +17 -0
- package/dist/utils/tool-helpers.js +99 -0
- package/package.json +14 -10
- package/dist/examples/llamacpp-tools-routing.d.ts +0 -2
- package/dist/examples/llamacpp-tools-routing.js +0 -364
- package/dist/examples/llamacpp-tools.d.ts +0 -2
- package/dist/examples/llamacpp-tools.js +0 -81
- package/dist/server/http-server.d.ts +0 -2
- package/dist/server/http-server.js +0 -189
|
@@ -1,364 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,81 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,189 +0,0 @@
|
|
|
1
|
-
// import http from "bare-http1";
|
|
2
|
-
// import process from "bare-process";
|
|
3
|
-
// import { loadModel, completion } from "./handlers/llamacpp";
|
|
4
|
-
// // import { loadWhisperModel, transcribe } from "./whisper.js";
|
|
5
|
-
export {};
|
|
6
|
-
// export type Request = http.HTTPIncomingMessage;
|
|
7
|
-
// export type Response = http.HTTPServerResponse;
|
|
8
|
-
// export type RouteHandler = (
|
|
9
|
-
// req: Request,
|
|
10
|
-
// res: Response
|
|
11
|
-
// ) => Promise<void>;
|
|
12
|
-
// // async function transcribeRoute(
|
|
13
|
-
// // req: http.Request,
|
|
14
|
-
// // res: http.Response
|
|
15
|
-
// // ): Promise<void> {
|
|
16
|
-
// // if (req.method !== 'POST') {
|
|
17
|
-
// // res.statusCode = 405;
|
|
18
|
-
// // res.setHeader('Content-Type', 'application/json');
|
|
19
|
-
// // const errorResponse = JSON.stringify({ error: 'Method not allowed' });
|
|
20
|
-
// // res.setHeader("Content-Length", errorResponse.length);
|
|
21
|
-
// // res.write(errorResponse);
|
|
22
|
-
// // res.end();
|
|
23
|
-
// // return;
|
|
24
|
-
// // }
|
|
25
|
-
// // try {
|
|
26
|
-
// // // Read the request body
|
|
27
|
-
// // let body = '';
|
|
28
|
-
// // req.on('data', (chunk) => {
|
|
29
|
-
// // body += chunk;
|
|
30
|
-
// // });
|
|
31
|
-
// // await new Promise((resolve) => {
|
|
32
|
-
// // req.on('end', resolve);
|
|
33
|
-
// // });
|
|
34
|
-
// // // Parse JSON body
|
|
35
|
-
// // const { audio: b64Audio } = JSON.parse(body);
|
|
36
|
-
// // if (!b64Audio) {
|
|
37
|
-
// // res.statusCode = 400;
|
|
38
|
-
// // res.setHeader('Content-Type', 'application/json');
|
|
39
|
-
// // const errorResponse = JSON.stringify({ error: 'Missing b64Audio in request body' });
|
|
40
|
-
// // res.setHeader("Content-Length", errorResponse.length);
|
|
41
|
-
// // res.write(errorResponse);
|
|
42
|
-
// // res.end();
|
|
43
|
-
// // return;
|
|
44
|
-
// // }
|
|
45
|
-
// // // Call transcribe function
|
|
46
|
-
// // const transcription = await transcribe(b64Audio);
|
|
47
|
-
// // // Return transcription result
|
|
48
|
-
// // res.statusCode = 200;
|
|
49
|
-
// // res.setHeader('Content-Type', 'application/json');
|
|
50
|
-
// // const response = JSON.stringify({ transcription });
|
|
51
|
-
// // res.setHeader("Content-Length", response.length);
|
|
52
|
-
// // res.write(response);
|
|
53
|
-
// // res.end();
|
|
54
|
-
// // } catch (error) {
|
|
55
|
-
// // console.error('Transcription error:', error);
|
|
56
|
-
// // res.statusCode = 500;
|
|
57
|
-
// // res.setHeader('Content-Type', 'application/json');
|
|
58
|
-
// // const errorResponse = JSON.stringify({ error: 'Internal server error' });
|
|
59
|
-
// // res.setHeader("Content-Length", errorResponse.length);
|
|
60
|
-
// // res.write(errorResponse);
|
|
61
|
-
// // res.end();
|
|
62
|
-
// // }
|
|
63
|
-
// // }
|
|
64
|
-
// async function completionRoute(
|
|
65
|
-
// req: Request,
|
|
66
|
-
// res: Response
|
|
67
|
-
// ): Promise<void> {
|
|
68
|
-
// if (req.method !== 'POST') {
|
|
69
|
-
// res.statusCode = 405;
|
|
70
|
-
// res.setHeader('Content-Type', 'application/json');
|
|
71
|
-
// const errorResponse = JSON.stringify({ error: 'Method not allowed' });
|
|
72
|
-
// res.setHeader("Content-Length", errorResponse.length);
|
|
73
|
-
// res.write(errorResponse);
|
|
74
|
-
// res.end();
|
|
75
|
-
// return;
|
|
76
|
-
// }
|
|
77
|
-
// try {
|
|
78
|
-
// // Read the request body
|
|
79
|
-
// let body = '';
|
|
80
|
-
// req.on('data', (chunk) => {
|
|
81
|
-
// body += chunk;
|
|
82
|
-
// });
|
|
83
|
-
// await new Promise((resolve) => {
|
|
84
|
-
// req.on('end', resolve);
|
|
85
|
-
// });
|
|
86
|
-
// // Parse JSON body
|
|
87
|
-
// const { messages } = JSON.parse(body);
|
|
88
|
-
// if (!messages || !Array.isArray(messages)) {
|
|
89
|
-
// res.statusCode = 400;
|
|
90
|
-
// res.setHeader('Content-Type', 'application/json');
|
|
91
|
-
// const errorResponse = JSON.stringify({ error: 'Missing or invalid messages in request body' });
|
|
92
|
-
// res.setHeader("Content-Length", errorResponse.length);
|
|
93
|
-
// res.write(errorResponse);
|
|
94
|
-
// res.end();
|
|
95
|
-
// return;
|
|
96
|
-
// }
|
|
97
|
-
// // Call completion function
|
|
98
|
-
// const response = await completion(messages);
|
|
99
|
-
// // Return completion result
|
|
100
|
-
// res.statusCode = 200;
|
|
101
|
-
// res.setHeader('Content-Type', 'application/json');
|
|
102
|
-
// const jsonResponse = JSON.stringify({ response });
|
|
103
|
-
// res.setHeader("Content-Length", jsonResponse.length);
|
|
104
|
-
// res.write(jsonResponse);
|
|
105
|
-
// res.end();
|
|
106
|
-
// } catch (error) {
|
|
107
|
-
// console.error('Completion error:', error);
|
|
108
|
-
// res.statusCode = 500;
|
|
109
|
-
// res.setHeader('Content-Type', 'application/json');
|
|
110
|
-
// const errorResponse = JSON.stringify({ error: 'Internal server error' });
|
|
111
|
-
// res.setHeader("Content-Length", errorResponse.length);
|
|
112
|
-
// res.write(errorResponse);
|
|
113
|
-
// res.end();
|
|
114
|
-
// }
|
|
115
|
-
// }
|
|
116
|
-
// export const routes: Record<string, RouteHandler> = {
|
|
117
|
-
// // '/transcribe': transcribeRoute,
|
|
118
|
-
// '/completion': completionRoute
|
|
119
|
-
// };
|
|
120
|
-
// export async function handleRequest(
|
|
121
|
-
// req: Request,
|
|
122
|
-
// res: Response
|
|
123
|
-
// ): Promise<void> {
|
|
124
|
-
// // Set CORS headers
|
|
125
|
-
// res.setHeader('Access-Control-Allow-Origin', '*');
|
|
126
|
-
// res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
|
|
127
|
-
// res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
|
|
128
|
-
// // Handle preflight requests
|
|
129
|
-
// if (req.method === 'OPTIONS') {
|
|
130
|
-
// res.statusCode = 200;
|
|
131
|
-
// res.end();
|
|
132
|
-
// return;
|
|
133
|
-
// }
|
|
134
|
-
// const url = new URL(req.url!, `http://${req.headers.host}`);
|
|
135
|
-
// const route = routes[url.pathname];
|
|
136
|
-
// if (route) {
|
|
137
|
-
// await route(req, res);
|
|
138
|
-
// } else {
|
|
139
|
-
// // Handle 404 for unknown routes
|
|
140
|
-
// res.statusCode = 404;
|
|
141
|
-
// res.setHeader('Content-Type', 'application/json');
|
|
142
|
-
// const errorResponse = JSON.stringify({ error: 'Route not found' });
|
|
143
|
-
// res.setHeader("Content-Length", errorResponse.length);
|
|
144
|
-
// res.write(errorResponse);
|
|
145
|
-
// res.end();
|
|
146
|
-
// }
|
|
147
|
-
// }
|
|
148
|
-
// async function startServer(port: number = 3000): Promise<void> {
|
|
149
|
-
// const server = http.createServer(handleRequest);
|
|
150
|
-
// server.listen(port, () => {
|
|
151
|
-
// console.log(`HTTP server listening on port ${port}`);
|
|
152
|
-
// });
|
|
153
|
-
// // Handle graceful shutdown
|
|
154
|
-
// process.on('SIGTERM', () => {
|
|
155
|
-
// console.log('Shutting down HTTP server...');
|
|
156
|
-
// server.close(() => {
|
|
157
|
-
// console.log('HTTP server closed');
|
|
158
|
-
// process.exit(0);
|
|
159
|
-
// });
|
|
160
|
-
// });
|
|
161
|
-
// process.on('SIGINT', () => {
|
|
162
|
-
// console.log('Shutting down HTTP server...');
|
|
163
|
-
// server.close(() => {
|
|
164
|
-
// console.log('HTTP server closed');
|
|
165
|
-
// process.exit(0);
|
|
166
|
-
// });
|
|
167
|
-
// });
|
|
168
|
-
// }
|
|
169
|
-
// // Main application startup
|
|
170
|
-
// async function main() {
|
|
171
|
-
// console.log("🚀 Starting QVAC Notes server...");
|
|
172
|
-
// try {
|
|
173
|
-
// // Load models on startup
|
|
174
|
-
// console.log("Loading Whisper model...");
|
|
175
|
-
// // await loadWhisperModel();
|
|
176
|
-
// console.log("✅ Whisper model loaded");
|
|
177
|
-
// // Load LLM model (you may want to make this configurable)
|
|
178
|
-
// console.log("Loading LLM model...");
|
|
179
|
-
// await loadModel("/Users/marco/.cache/lm-studio/models/lmstudio-community/medgemma-4b-it-GGUF/medgemma-4b-it-Q4_K_M.gguf");
|
|
180
|
-
// console.log("✅ LLM model loaded");
|
|
181
|
-
// // Start HTTP server
|
|
182
|
-
// await startServer();
|
|
183
|
-
// } catch (error) {
|
|
184
|
-
// console.error("❌ Failed to start server:", error);
|
|
185
|
-
// process.exit(1);
|
|
186
|
-
// }
|
|
187
|
-
// }
|
|
188
|
-
// // Start the server
|
|
189
|
-
// main().catch(console.error);
|