ai-speedometer-headless 2.1.7 → 2.2.0

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.
@@ -651,16 +651,17 @@ async function benchmarkSingleModelRest(model, logger) {
651
651
  continue;
652
652
  try {
653
653
  if (model.providerType === "anthropic") {
654
- if (trimmedLine.startsWith("data: ")) {
655
- const jsonStr = trimmedLine.slice(6);
654
+ const anthropicDataPrefix = trimmedLine.startsWith("data: ") ? 6 : trimmedLine.startsWith("data:") ? 5 : -1;
655
+ if (anthropicDataPrefix !== -1) {
656
+ const jsonStr = trimmedLine.slice(anthropicDataPrefix);
656
657
  if (jsonStr === "[DONE]")
657
658
  continue;
658
659
  const chunk = JSON.parse(jsonStr);
659
660
  const chunkTyped = chunk;
660
- if (chunkTyped.type === "content_block_delta" && chunkTyped.delta?.text) {
661
+ if (chunkTyped.type === "content_block_delta" && (chunkTyped.delta?.text || chunkTyped.delta?.thinking)) {
661
662
  if (!firstParsedTokenTime)
662
663
  firstParsedTokenTime = Date.now();
663
- streamedText += chunkTyped.delta.text;
664
+ streamedText += chunkTyped.delta?.text || chunkTyped.delta?.thinking || "";
664
665
  } else if (chunkTyped.type === "message_start" && chunkTyped.message?.usage) {
665
666
  inputTokens = chunkTyped.message.usage.input_tokens || 0;
666
667
  } else if (chunkTyped.type === "message_delta") {
@@ -673,10 +674,10 @@ async function benchmarkSingleModelRest(model, logger) {
673
674
  continue;
674
675
  } else {
675
676
  const chunk = JSON.parse(trimmedLine);
676
- if (chunk.type === "content_block_delta" && chunk.delta?.text) {
677
+ if (chunk.type === "content_block_delta" && (chunk.delta?.text || chunk.delta?.thinking)) {
677
678
  if (!firstParsedTokenTime)
678
679
  firstParsedTokenTime = Date.now();
679
- streamedText += chunk.delta.text;
680
+ streamedText += chunk.delta?.text || chunk.delta?.thinking || "";
680
681
  } else if (chunk.type === "message_start" && chunk.message?.usage) {
681
682
  inputTokens = chunk.message.usage.input_tokens || 0;
682
683
  } else if (chunk.type === "message_delta") {
@@ -698,24 +699,42 @@ async function benchmarkSingleModelRest(model, logger) {
698
699
  if (chunk.usageMetadata?.candidatesTokenCount)
699
700
  outputTokens = chunk.usageMetadata.candidatesTokenCount;
700
701
  } else {
701
- if (trimmedLine.startsWith("data: ")) {
702
- const jsonStr = trimmedLine.slice(6);
703
- if (jsonStr === "[DONE]")
704
- continue;
705
- const chunk = JSON.parse(jsonStr);
706
- if (chunk.choices?.[0]?.delta?.content) {
707
- if (!firstParsedTokenTime)
708
- firstParsedTokenTime = Date.now();
709
- streamedText += chunk.choices[0].delta.content;
710
- } else if (chunk.choices?.[0]?.delta?.reasoning) {
711
- if (!firstParsedTokenTime)
712
- firstParsedTokenTime = Date.now();
713
- streamedText += chunk.choices[0].delta.reasoning;
714
- }
715
- if (chunk.usage?.prompt_tokens)
716
- inputTokens = chunk.usage.prompt_tokens;
717
- if (chunk.usage?.completion_tokens)
718
- outputTokens = chunk.usage.completion_tokens;
702
+ const dataPrefix = trimmedLine.startsWith("data: ") ? 6 : trimmedLine.startsWith("data:") ? 5 : -1;
703
+ if (dataPrefix === -1)
704
+ continue;
705
+ const jsonStr = trimmedLine.slice(dataPrefix);
706
+ if (jsonStr === "[DONE]")
707
+ continue;
708
+ const chunk = JSON.parse(jsonStr);
709
+ if (chunk.choices?.[0]?.delta?.content) {
710
+ if (!firstParsedTokenTime)
711
+ firstParsedTokenTime = Date.now();
712
+ streamedText += chunk.choices[0].delta.content;
713
+ } else if (chunk.choices?.[0]?.delta?.reasoning) {
714
+ if (!firstParsedTokenTime)
715
+ firstParsedTokenTime = Date.now();
716
+ streamedText += chunk.choices[0].delta.reasoning;
717
+ } else if (chunk.choices?.[0]?.delta?.reasoning_content) {
718
+ if (!firstParsedTokenTime)
719
+ firstParsedTokenTime = Date.now();
720
+ streamedText += chunk.choices[0].delta.reasoning_content;
721
+ } else if (chunk.type === "content_block_delta" && chunk.delta?.text) {
722
+ if (!firstParsedTokenTime)
723
+ firstParsedTokenTime = Date.now();
724
+ streamedText += chunk.delta.text;
725
+ } else if (chunk.type === "content_block_delta" && chunk.delta?.thinking) {
726
+ if (!firstParsedTokenTime)
727
+ firstParsedTokenTime = Date.now();
728
+ streamedText += chunk.delta.thinking;
729
+ }
730
+ if (chunk.usage?.prompt_tokens)
731
+ inputTokens = chunk.usage.prompt_tokens;
732
+ if (chunk.usage?.completion_tokens)
733
+ outputTokens = chunk.usage.completion_tokens;
734
+ if (chunk.type === "message_start" && chunk.message?.usage?.input_tokens)
735
+ inputTokens = chunk.message.usage.input_tokens;
736
+ if (chunk.type === "message_delta" && chunk.usage?.output_tokens) {
737
+ outputTokens = chunk.usage.output_tokens;
719
738
  }
720
739
  }
721
740
  } catch {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-speedometer-headless",
3
- "version": "2.1.7",
3
+ "version": "2.2.0",
4
4
  "description": "Headless CLI for benchmarking AI models — runs on Node.js and Bun, no TUI dependencies",
5
5
  "bin": {
6
6
  "ai-speedometer-headless": "dist/ai-speedometer-headless"