ai-speedometer 2.1.4 → 2.1.6
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/dist/ai-speedometer +115 -30
- package/package.json +1 -1
package/dist/ai-speedometer
CHANGED
|
@@ -1762,7 +1762,8 @@ async function benchmarkSingleModelRest(model) {
|
|
|
1762
1762
|
messages: [{ role: "user", content: TEST_PROMPT }],
|
|
1763
1763
|
max_tokens: 500,
|
|
1764
1764
|
temperature: 0.7,
|
|
1765
|
-
stream: true
|
|
1765
|
+
stream: true,
|
|
1766
|
+
stream_options: { include_usage: true }
|
|
1766
1767
|
};
|
|
1767
1768
|
if (model.providerType === "google") {
|
|
1768
1769
|
body["contents"] = [{ parts: [{ text: TEST_PROMPT }] }];
|
|
@@ -1770,6 +1771,9 @@ async function benchmarkSingleModelRest(model) {
|
|
|
1770
1771
|
delete body["messages"];
|
|
1771
1772
|
delete body["max_tokens"];
|
|
1772
1773
|
delete body["stream"];
|
|
1774
|
+
delete body["stream_options"];
|
|
1775
|
+
} else if (model.providerType === "anthropic") {
|
|
1776
|
+
delete body["stream_options"];
|
|
1773
1777
|
}
|
|
1774
1778
|
const response = await fetch(url, {
|
|
1775
1779
|
method: "POST",
|
|
@@ -1777,8 +1781,22 @@ async function benchmarkSingleModelRest(model) {
|
|
|
1777
1781
|
body: JSON.stringify(body)
|
|
1778
1782
|
});
|
|
1779
1783
|
if (!response.ok) {
|
|
1780
|
-
await response.text();
|
|
1781
|
-
|
|
1784
|
+
const errBody = await response.text();
|
|
1785
|
+
let errDetail = "";
|
|
1786
|
+
try {
|
|
1787
|
+
const parsed = JSON.parse(errBody);
|
|
1788
|
+
if (typeof parsed.error === "object" && parsed.error?.message)
|
|
1789
|
+
errDetail = parsed.error.message;
|
|
1790
|
+
else if (typeof parsed.error === "string")
|
|
1791
|
+
errDetail = parsed.error;
|
|
1792
|
+
else if (parsed.message)
|
|
1793
|
+
errDetail = parsed.message;
|
|
1794
|
+
else
|
|
1795
|
+
errDetail = errBody.slice(0, 200);
|
|
1796
|
+
} catch {
|
|
1797
|
+
errDetail = errBody.slice(0, 200);
|
|
1798
|
+
}
|
|
1799
|
+
throw new Error(`${response.status} ${response.statusText}${errDetail ? ": " + errDetail : ""}`);
|
|
1782
1800
|
}
|
|
1783
1801
|
const reader = response.body.getReader();
|
|
1784
1802
|
const decoder = new TextDecoder;
|
|
@@ -1805,7 +1823,7 @@ async function benchmarkSingleModelRest(model) {
|
|
|
1805
1823
|
if (trimmedLine.startsWith("data: ")) {
|
|
1806
1824
|
const jsonStr = trimmedLine.slice(6);
|
|
1807
1825
|
if (jsonStr === "[DONE]")
|
|
1808
|
-
|
|
1826
|
+
continue;
|
|
1809
1827
|
const chunk = JSON.parse(jsonStr);
|
|
1810
1828
|
const chunkTyped = chunk;
|
|
1811
1829
|
if (chunkTyped.type === "content_block_delta" && chunkTyped.delta?.text) {
|
|
@@ -1846,7 +1864,7 @@ async function benchmarkSingleModelRest(model) {
|
|
|
1846
1864
|
if (trimmedLine.startsWith("data: ")) {
|
|
1847
1865
|
const jsonStr = trimmedLine.slice(6);
|
|
1848
1866
|
if (jsonStr === "[DONE]")
|
|
1849
|
-
|
|
1867
|
+
continue;
|
|
1850
1868
|
const chunk = JSON.parse(jsonStr);
|
|
1851
1869
|
if (chunk.choices?.[0]?.delta?.content)
|
|
1852
1870
|
streamedText += chunk.choices[0].delta.content;
|
|
@@ -2161,7 +2179,7 @@ var package_default;
|
|
|
2161
2179
|
var init_package = __esm(() => {
|
|
2162
2180
|
package_default = {
|
|
2163
2181
|
name: "ai-speedometer",
|
|
2164
|
-
version: "2.1.
|
|
2182
|
+
version: "2.1.6",
|
|
2165
2183
|
description: "A comprehensive CLI tool for benchmarking AI models across multiple providers with parallel execution and professional metrics",
|
|
2166
2184
|
bin: {
|
|
2167
2185
|
"ai-speedometer": "dist/ai-speedometer",
|
|
@@ -2614,7 +2632,7 @@ function ModelSelectScreen() {
|
|
|
2614
2632
|
navigate("benchmark");
|
|
2615
2633
|
}, [dispatch, navigate]);
|
|
2616
2634
|
usePaste((text) => {
|
|
2617
|
-
setSearchQuery((q) => q + text);
|
|
2635
|
+
setSearchQuery((q) => q + text.replace(/[\r\n]/g, ""));
|
|
2618
2636
|
});
|
|
2619
2637
|
useKeyboard4((key) => {
|
|
2620
2638
|
if (key.name === "escape") {
|
|
@@ -2658,15 +2676,15 @@ function ModelSelectScreen() {
|
|
|
2658
2676
|
}
|
|
2659
2677
|
return;
|
|
2660
2678
|
}
|
|
2661
|
-
if (!searchQuery &&
|
|
2679
|
+
if (!searchQuery && key.sequence === "A") {
|
|
2662
2680
|
setSelected(new Set(orderedModels.map((m) => m.key)));
|
|
2663
2681
|
return;
|
|
2664
2682
|
}
|
|
2665
|
-
if (!searchQuery &&
|
|
2683
|
+
if (!searchQuery && key.sequence === "N") {
|
|
2666
2684
|
setSelected(new Set);
|
|
2667
2685
|
return;
|
|
2668
2686
|
}
|
|
2669
|
-
if (!searchQuery && recentCount > 0 &&
|
|
2687
|
+
if (!searchQuery && recentCount > 0 && key.sequence === "R") {
|
|
2670
2688
|
launchBench(orderedModels.slice(0, recentCount));
|
|
2671
2689
|
return;
|
|
2672
2690
|
}
|
|
@@ -3307,6 +3325,68 @@ function BenchmarkScreen() {
|
|
|
3307
3325
|
}, `ttft-${s.model.id}-${s.model.providerId}`, true, undefined, this));
|
|
3308
3326
|
}
|
|
3309
3327
|
}
|
|
3328
|
+
if (allDone && errors.length > 0) {
|
|
3329
|
+
rows.push(/* @__PURE__ */ jsxDEV10("box", {
|
|
3330
|
+
height: 1,
|
|
3331
|
+
backgroundColor: "#292e42"
|
|
3332
|
+
}, "div-errors", false, undefined, this));
|
|
3333
|
+
rows.push(/* @__PURE__ */ jsxDEV10("box", {
|
|
3334
|
+
height: 1,
|
|
3335
|
+
flexDirection: "row",
|
|
3336
|
+
paddingLeft: 1,
|
|
3337
|
+
children: /* @__PURE__ */ jsxDEV10("text", {
|
|
3338
|
+
fg: "#f7768e",
|
|
3339
|
+
children: [
|
|
3340
|
+
" FAILED (",
|
|
3341
|
+
errors.length,
|
|
3342
|
+
") "
|
|
3343
|
+
]
|
|
3344
|
+
}, undefined, true, undefined, this)
|
|
3345
|
+
}, "hdr-errors", false, undefined, this));
|
|
3346
|
+
for (const s of errors) {
|
|
3347
|
+
rows.push(/* @__PURE__ */ jsxDEV10("box", {
|
|
3348
|
+
flexDirection: "column",
|
|
3349
|
+
paddingLeft: 2,
|
|
3350
|
+
paddingTop: 1,
|
|
3351
|
+
paddingBottom: 1,
|
|
3352
|
+
children: [
|
|
3353
|
+
/* @__PURE__ */ jsxDEV10("box", {
|
|
3354
|
+
height: 1,
|
|
3355
|
+
flexDirection: "row",
|
|
3356
|
+
children: [
|
|
3357
|
+
/* @__PURE__ */ jsxDEV10("text", {
|
|
3358
|
+
fg: "#f7768e",
|
|
3359
|
+
children: "\u2717 "
|
|
3360
|
+
}, undefined, false, undefined, this),
|
|
3361
|
+
/* @__PURE__ */ jsxDEV10("text", {
|
|
3362
|
+
fg: "#c0caf5",
|
|
3363
|
+
children: [
|
|
3364
|
+
s.model.name,
|
|
3365
|
+
" "
|
|
3366
|
+
]
|
|
3367
|
+
}, undefined, true, undefined, this),
|
|
3368
|
+
/* @__PURE__ */ jsxDEV10("text", {
|
|
3369
|
+
fg: "#565f89",
|
|
3370
|
+
children: [
|
|
3371
|
+
"(",
|
|
3372
|
+
s.model.providerName,
|
|
3373
|
+
")"
|
|
3374
|
+
]
|
|
3375
|
+
}, undefined, true, undefined, this)
|
|
3376
|
+
]
|
|
3377
|
+
}, undefined, true, undefined, this),
|
|
3378
|
+
/* @__PURE__ */ jsxDEV10("box", {
|
|
3379
|
+
height: 1,
|
|
3380
|
+
paddingLeft: 3,
|
|
3381
|
+
children: /* @__PURE__ */ jsxDEV10("text", {
|
|
3382
|
+
fg: "#f7768e",
|
|
3383
|
+
children: s.error ?? "Unknown error"
|
|
3384
|
+
}, undefined, false, undefined, this)
|
|
3385
|
+
}, undefined, false, undefined, this)
|
|
3386
|
+
]
|
|
3387
|
+
}, `err-${s.model.id}-${s.model.providerId}`, true, undefined, this));
|
|
3388
|
+
}
|
|
3389
|
+
}
|
|
3310
3390
|
rows.push(/* @__PURE__ */ jsxDEV10("box", {
|
|
3311
3391
|
height: 1,
|
|
3312
3392
|
backgroundColor: "#292e42"
|
|
@@ -3515,10 +3595,11 @@ function AddVerifiedScreen() {
|
|
|
3515
3595
|
}
|
|
3516
3596
|
}
|
|
3517
3597
|
usePaste((text) => {
|
|
3598
|
+
const clean = text.replace(/[\r\n]/g, "");
|
|
3518
3599
|
if (step === "browse")
|
|
3519
|
-
setSearchQuery((q) => q +
|
|
3600
|
+
setSearchQuery((q) => q + clean);
|
|
3520
3601
|
else if (step === "confirm")
|
|
3521
|
-
setApiKey((k) => k +
|
|
3602
|
+
setApiKey((k) => k + clean);
|
|
3522
3603
|
});
|
|
3523
3604
|
useKeyboard6((key) => {
|
|
3524
3605
|
if (step === "browse") {
|
|
@@ -3930,7 +4011,7 @@ function AddCustomScreen() {
|
|
|
3930
4011
|
baseUrl: baseUrl.trim(),
|
|
3931
4012
|
apiKey: apiKey.trim(),
|
|
3932
4013
|
models: models.map((m) => ({
|
|
3933
|
-
id: m
|
|
4014
|
+
id: m,
|
|
3934
4015
|
name: m
|
|
3935
4016
|
}))
|
|
3936
4017
|
});
|
|
@@ -3945,16 +4026,17 @@ function AddCustomScreen() {
|
|
|
3945
4026
|
}
|
|
3946
4027
|
}
|
|
3947
4028
|
usePaste((text) => {
|
|
4029
|
+
const clean = text.replace(/[\r\n]/g, "");
|
|
3948
4030
|
if (step === "id")
|
|
3949
|
-
setProviderId((v) => v +
|
|
4031
|
+
setProviderId((v) => v + clean);
|
|
3950
4032
|
else if (step === "name")
|
|
3951
|
-
setProviderName((v) => v +
|
|
4033
|
+
setProviderName((v) => v + clean);
|
|
3952
4034
|
else if (step === "url")
|
|
3953
|
-
setBaseUrl((v) => v +
|
|
4035
|
+
setBaseUrl((v) => v + clean);
|
|
3954
4036
|
else if (step === "key")
|
|
3955
|
-
setApiKey((v) => v +
|
|
4037
|
+
setApiKey((v) => v + clean);
|
|
3956
4038
|
else if (step === "models")
|
|
3957
|
-
setModelInput((v) => v +
|
|
4039
|
+
setModelInput((v) => v + clean);
|
|
3958
4040
|
});
|
|
3959
4041
|
useKeyboard7((key) => {
|
|
3960
4042
|
if (step === "done") {
|
|
@@ -4018,10 +4100,8 @@ function AddCustomScreen() {
|
|
|
4018
4100
|
}
|
|
4019
4101
|
if (step === "name") {
|
|
4020
4102
|
if (key.name === "return" || key.name === "enter") {
|
|
4021
|
-
if (!providerName.trim())
|
|
4022
|
-
|
|
4023
|
-
return;
|
|
4024
|
-
}
|
|
4103
|
+
if (!providerName.trim())
|
|
4104
|
+
setProviderName(providerId);
|
|
4025
4105
|
setInputError("");
|
|
4026
4106
|
setStep("url");
|
|
4027
4107
|
return;
|
|
@@ -4310,8 +4390,12 @@ function AddCustomScreen() {
|
|
|
4310
4390
|
height: 1,
|
|
4311
4391
|
children: /* @__PURE__ */ jsxDEV12("text", {
|
|
4312
4392
|
fg: "#565f89",
|
|
4313
|
-
children:
|
|
4314
|
-
|
|
4393
|
+
children: [
|
|
4394
|
+
'e.g. My OpenAI (Enter to use "',
|
|
4395
|
+
providerId,
|
|
4396
|
+
'")'
|
|
4397
|
+
]
|
|
4398
|
+
}, undefined, true, undefined, this)
|
|
4315
4399
|
}, undefined, false, undefined, this)
|
|
4316
4400
|
]
|
|
4317
4401
|
}, undefined, true, undefined, this),
|
|
@@ -4485,8 +4569,9 @@ function AddModelsScreen() {
|
|
|
4485
4569
|
load();
|
|
4486
4570
|
}, []);
|
|
4487
4571
|
usePaste((text) => {
|
|
4572
|
+
const clean = text.replace(/[\r\n]/g, "");
|
|
4488
4573
|
if (step === "add")
|
|
4489
|
-
setModelInput((v) => v +
|
|
4574
|
+
setModelInput((v) => v + clean);
|
|
4490
4575
|
});
|
|
4491
4576
|
useKeyboard8((key) => {
|
|
4492
4577
|
if (done) {
|
|
@@ -4947,23 +5032,23 @@ function getHints(screen, benchResults) {
|
|
|
4947
5032
|
case "main-menu":
|
|
4948
5033
|
return ["[\u2191\u2193] navigate", "[Enter] select", "[Ctrl+C] quit"];
|
|
4949
5034
|
case "model-menu":
|
|
4950
|
-
return ["[\u2191\u2193] navigate", "[Enter] select", "[
|
|
5035
|
+
return ["[\u2191\u2193] navigate", "[Enter] select", "[Q] back"];
|
|
4951
5036
|
case "model-select":
|
|
4952
5037
|
return ["[\u2191\u2193] navigate", "[Tab] select", "[Enter] run", "[A] all", "[N] none", "[R] recent", "[Esc] back"];
|
|
4953
5038
|
case "benchmark": {
|
|
4954
5039
|
const allDone = benchResults.length > 0 && benchResults.every((r) => r.status === "done" || r.status === "error");
|
|
4955
|
-
return allDone ? ["[Enter] back to menu", "[
|
|
5040
|
+
return allDone ? ["[Enter] back to menu", "[Q] back to menu"] : ["Benchmark in progress..."];
|
|
4956
5041
|
}
|
|
4957
5042
|
case "list-providers":
|
|
4958
|
-
return ["[\u2191\u2193] scroll", "[
|
|
5043
|
+
return ["[\u2191\u2193] scroll", "[Q] back"];
|
|
4959
5044
|
case "add-verified":
|
|
4960
|
-
return ["[\u2191\u2193] navigate", "[Enter] select", "[
|
|
5045
|
+
return ["[\u2191\u2193] navigate", "[Enter] select", "[Q] back"];
|
|
4961
5046
|
case "add-custom":
|
|
4962
5047
|
return ["[\u2191\u2193] navigate", "[Enter] confirm", "[Esc] back"];
|
|
4963
5048
|
case "add-models":
|
|
4964
5049
|
return ["[\u2191\u2193] navigate", "[Enter] add / finish", "[Esc] back"];
|
|
4965
5050
|
default:
|
|
4966
|
-
return ["[
|
|
5051
|
+
return ["[Q] back"];
|
|
4967
5052
|
}
|
|
4968
5053
|
}
|
|
4969
5054
|
function ActiveScreen() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai-speedometer",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.6",
|
|
4
4
|
"description": "A comprehensive CLI tool for benchmarking AI models across multiple providers with parallel execution and professional metrics",
|
|
5
5
|
"bin": {
|
|
6
6
|
"ai-speedometer": "dist/ai-speedometer",
|