ai-speedometer-headless 2.1.6 → 2.1.7
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-headless +25 -9
- package/package.json +1 -1
|
@@ -542,7 +542,7 @@ var getAllAvailableProviders = async (includeAllProviders = false) => {
|
|
|
542
542
|
var TEST_PROMPT = `make a 300 word story`;
|
|
543
543
|
|
|
544
544
|
// ../core/src/benchmark.ts
|
|
545
|
-
async function benchmarkSingleModelRest(model) {
|
|
545
|
+
async function benchmarkSingleModelRest(model, logger) {
|
|
546
546
|
try {
|
|
547
547
|
if (!model.providerConfig || !model.providerConfig.apiKey) {
|
|
548
548
|
throw new Error(`Missing API key for provider ${model.providerName}`);
|
|
@@ -559,6 +559,7 @@ async function benchmarkSingleModelRest(model) {
|
|
|
559
559
|
actualModelId = model.name;
|
|
560
560
|
}
|
|
561
561
|
actualModelId = actualModelId.trim();
|
|
562
|
+
await logger?.logHeader(model.name, model.providerName, model.providerConfig.apiKey);
|
|
562
563
|
const startTime = Date.now();
|
|
563
564
|
let firstTokenTime = null;
|
|
564
565
|
let streamedText = "";
|
|
@@ -631,21 +632,21 @@ async function benchmarkSingleModelRest(model) {
|
|
|
631
632
|
const reader = response.body.getReader();
|
|
632
633
|
const decoder = new TextDecoder;
|
|
633
634
|
let buffer = "";
|
|
634
|
-
let
|
|
635
|
+
let firstParsedTokenTime = null;
|
|
635
636
|
while (true) {
|
|
636
637
|
const { done, value } = await reader.read();
|
|
637
638
|
if (done)
|
|
638
639
|
break;
|
|
639
|
-
if (
|
|
640
|
+
if (!firstTokenTime)
|
|
640
641
|
firstTokenTime = Date.now();
|
|
641
|
-
isFirstChunk = false;
|
|
642
|
-
}
|
|
643
642
|
buffer += decoder.decode(value, { stream: true });
|
|
644
643
|
const lines = buffer.split(`
|
|
645
644
|
`);
|
|
646
645
|
buffer = lines.pop() || "";
|
|
647
646
|
for (const line of lines) {
|
|
648
647
|
const trimmedLine = line.trim();
|
|
648
|
+
if (trimmedLine)
|
|
649
|
+
await logger?.logRaw(trimmedLine);
|
|
649
650
|
if (!trimmedLine)
|
|
650
651
|
continue;
|
|
651
652
|
try {
|
|
@@ -657,6 +658,8 @@ async function benchmarkSingleModelRest(model) {
|
|
|
657
658
|
const chunk = JSON.parse(jsonStr);
|
|
658
659
|
const chunkTyped = chunk;
|
|
659
660
|
if (chunkTyped.type === "content_block_delta" && chunkTyped.delta?.text) {
|
|
661
|
+
if (!firstParsedTokenTime)
|
|
662
|
+
firstParsedTokenTime = Date.now();
|
|
660
663
|
streamedText += chunkTyped.delta.text;
|
|
661
664
|
} else if (chunkTyped.type === "message_start" && chunkTyped.message?.usage) {
|
|
662
665
|
inputTokens = chunkTyped.message.usage.input_tokens || 0;
|
|
@@ -671,6 +674,8 @@ async function benchmarkSingleModelRest(model) {
|
|
|
671
674
|
} else {
|
|
672
675
|
const chunk = JSON.parse(trimmedLine);
|
|
673
676
|
if (chunk.type === "content_block_delta" && chunk.delta?.text) {
|
|
677
|
+
if (!firstParsedTokenTime)
|
|
678
|
+
firstParsedTokenTime = Date.now();
|
|
674
679
|
streamedText += chunk.delta.text;
|
|
675
680
|
} else if (chunk.type === "message_start" && chunk.message?.usage) {
|
|
676
681
|
inputTokens = chunk.message.usage.input_tokens || 0;
|
|
@@ -684,6 +689,8 @@ async function benchmarkSingleModelRest(model) {
|
|
|
684
689
|
} else if (model.providerType === "google") {
|
|
685
690
|
const chunk = JSON.parse(trimmedLine);
|
|
686
691
|
if (chunk.candidates?.[0]?.content?.parts?.[0]?.text) {
|
|
692
|
+
if (!firstParsedTokenTime)
|
|
693
|
+
firstParsedTokenTime = Date.now();
|
|
687
694
|
streamedText += chunk.candidates[0].content.parts[0].text;
|
|
688
695
|
}
|
|
689
696
|
if (chunk.usageMetadata?.promptTokenCount)
|
|
@@ -696,10 +703,15 @@ async function benchmarkSingleModelRest(model) {
|
|
|
696
703
|
if (jsonStr === "[DONE]")
|
|
697
704
|
continue;
|
|
698
705
|
const chunk = JSON.parse(jsonStr);
|
|
699
|
-
if (chunk.choices?.[0]?.delta?.content)
|
|
706
|
+
if (chunk.choices?.[0]?.delta?.content) {
|
|
707
|
+
if (!firstParsedTokenTime)
|
|
708
|
+
firstParsedTokenTime = Date.now();
|
|
700
709
|
streamedText += chunk.choices[0].delta.content;
|
|
701
|
-
else if (chunk.choices?.[0]?.delta?.reasoning)
|
|
710
|
+
} else if (chunk.choices?.[0]?.delta?.reasoning) {
|
|
711
|
+
if (!firstParsedTokenTime)
|
|
712
|
+
firstParsedTokenTime = Date.now();
|
|
702
713
|
streamedText += chunk.choices[0].delta.reasoning;
|
|
714
|
+
}
|
|
703
715
|
if (chunk.usage?.prompt_tokens)
|
|
704
716
|
inputTokens = chunk.usage.prompt_tokens;
|
|
705
717
|
if (chunk.usage?.completion_tokens)
|
|
@@ -711,15 +723,18 @@ async function benchmarkSingleModelRest(model) {
|
|
|
711
723
|
}
|
|
712
724
|
}
|
|
713
725
|
}
|
|
726
|
+
await logger?.flush();
|
|
714
727
|
const endTime = Date.now();
|
|
715
728
|
const totalTime = endTime - startTime;
|
|
716
|
-
const
|
|
729
|
+
const effectiveFirstToken = firstParsedTokenTime ?? firstTokenTime;
|
|
730
|
+
const timeToFirstToken = effectiveFirstToken ? effectiveFirstToken - startTime : totalTime;
|
|
731
|
+
const generationTime = totalTime - timeToFirstToken;
|
|
717
732
|
const usedEstimateForOutput = !outputTokens;
|
|
718
733
|
const usedEstimateForInput = !inputTokens;
|
|
719
734
|
const finalOutputTokens = outputTokens || Math.round(streamedText.length / 4);
|
|
720
735
|
const finalInputTokens = inputTokens || Math.round(TEST_PROMPT.length / 4);
|
|
721
736
|
const totalTokens = finalInputTokens + finalOutputTokens;
|
|
722
|
-
const tokensPerSecond =
|
|
737
|
+
const tokensPerSecond = generationTime > 0 ? finalOutputTokens / generationTime * 1000 : 0;
|
|
723
738
|
return {
|
|
724
739
|
model: model.name,
|
|
725
740
|
provider: model.providerName,
|
|
@@ -734,6 +749,7 @@ async function benchmarkSingleModelRest(model) {
|
|
|
734
749
|
success: true
|
|
735
750
|
};
|
|
736
751
|
} catch (error) {
|
|
752
|
+
await logger?.flush();
|
|
737
753
|
return {
|
|
738
754
|
model: model.name,
|
|
739
755
|
provider: model.providerName,
|
package/package.json
CHANGED