@langchain/google-genai 0.2.16 → 0.2.18

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.
@@ -403,7 +403,10 @@ class ChatGoogleGenerativeAI extends chat_models_1.BaseChatModel {
403
403
  get _isMultimodalModel() {
404
404
  return (this.model.includes("vision") ||
405
405
  this.model.startsWith("gemini-1.5") ||
406
- this.model.startsWith("gemini-2"));
406
+ this.model.startsWith("gemini-2") ||
407
+ (this.model.startsWith("gemma-3-") &&
408
+ !this.model.startsWith("gemma-3-1b")) // gemma-3 models are multimodal(but gemma-3n-* and gemma-3-1b are not)
409
+ );
407
410
  }
408
411
  constructor(fields) {
409
412
  super(fields);
@@ -694,30 +697,32 @@ class ChatGoogleGenerativeAI extends chat_models_1.BaseChatModel {
694
697
  return stream;
695
698
  });
696
699
  let usageMetadata;
700
+ // Keep prior cumulative counts for calculating token deltas while streaming
701
+ let prevPromptTokenCount = 0;
702
+ let prevCandidatesTokenCount = 0;
703
+ let prevTotalTokenCount = 0;
697
704
  let index = 0;
698
705
  for await (const response of stream) {
699
706
  if ("usageMetadata" in response &&
707
+ response.usageMetadata !== undefined &&
700
708
  this.streamUsage !== false &&
701
709
  options.streamUsage !== false) {
702
- const genAIUsageMetadata = response.usageMetadata;
703
- if (!usageMetadata) {
704
- usageMetadata = {
705
- input_tokens: genAIUsageMetadata.promptTokenCount ?? 0,
706
- output_tokens: genAIUsageMetadata.candidatesTokenCount ?? 0,
707
- total_tokens: genAIUsageMetadata.totalTokenCount ?? 0,
708
- };
709
- }
710
- else {
711
- // Under the hood, LangChain combines the prompt tokens. Google returns the updated
712
- // total each time, so we need to find the difference between the tokens.
713
- const outputTokenDiff = (genAIUsageMetadata.candidatesTokenCount ?? 0) -
714
- usageMetadata.output_tokens;
715
- usageMetadata = {
716
- input_tokens: 0,
717
- output_tokens: outputTokenDiff,
718
- total_tokens: outputTokenDiff,
719
- };
720
- }
710
+ usageMetadata = {
711
+ input_tokens: response.usageMetadata.promptTokenCount ?? 0,
712
+ output_tokens: response.usageMetadata.candidatesTokenCount ?? 0,
713
+ total_tokens: response.usageMetadata.totalTokenCount ?? 0,
714
+ };
715
+ // Under the hood, LangChain combines the prompt tokens. Google returns the updated
716
+ // total each time, so we need to find the difference between the tokens.
717
+ const newPromptTokenCount = response.usageMetadata.promptTokenCount ?? 0;
718
+ usageMetadata.input_tokens = Math.max(0, newPromptTokenCount - prevPromptTokenCount);
719
+ prevPromptTokenCount = newPromptTokenCount;
720
+ const newCandidatesTokenCount = response.usageMetadata.candidatesTokenCount ?? 0;
721
+ usageMetadata.output_tokens = Math.max(0, newCandidatesTokenCount - prevCandidatesTokenCount);
722
+ prevCandidatesTokenCount = newCandidatesTokenCount;
723
+ const newTotalTokenCount = response.usageMetadata.totalTokenCount ?? 0;
724
+ usageMetadata.total_tokens = Math.max(0, newTotalTokenCount - prevTotalTokenCount);
725
+ prevTotalTokenCount = newTotalTokenCount;
721
726
  }
722
727
  const chunk = (0, common_js_1.convertResponseContentToChatGenerationChunk)(response, {
723
728
  usageMetadata,
@@ -400,7 +400,10 @@ export class ChatGoogleGenerativeAI extends BaseChatModel {
400
400
  get _isMultimodalModel() {
401
401
  return (this.model.includes("vision") ||
402
402
  this.model.startsWith("gemini-1.5") ||
403
- this.model.startsWith("gemini-2"));
403
+ this.model.startsWith("gemini-2") ||
404
+ (this.model.startsWith("gemma-3-") &&
405
+ !this.model.startsWith("gemma-3-1b")) // gemma-3 models are multimodal(but gemma-3n-* and gemma-3-1b are not)
406
+ );
404
407
  }
405
408
  constructor(fields) {
406
409
  super(fields);
@@ -691,30 +694,32 @@ export class ChatGoogleGenerativeAI extends BaseChatModel {
691
694
  return stream;
692
695
  });
693
696
  let usageMetadata;
697
+ // Keep prior cumulative counts for calculating token deltas while streaming
698
+ let prevPromptTokenCount = 0;
699
+ let prevCandidatesTokenCount = 0;
700
+ let prevTotalTokenCount = 0;
694
701
  let index = 0;
695
702
  for await (const response of stream) {
696
703
  if ("usageMetadata" in response &&
704
+ response.usageMetadata !== undefined &&
697
705
  this.streamUsage !== false &&
698
706
  options.streamUsage !== false) {
699
- const genAIUsageMetadata = response.usageMetadata;
700
- if (!usageMetadata) {
701
- usageMetadata = {
702
- input_tokens: genAIUsageMetadata.promptTokenCount ?? 0,
703
- output_tokens: genAIUsageMetadata.candidatesTokenCount ?? 0,
704
- total_tokens: genAIUsageMetadata.totalTokenCount ?? 0,
705
- };
706
- }
707
- else {
708
- // Under the hood, LangChain combines the prompt tokens. Google returns the updated
709
- // total each time, so we need to find the difference between the tokens.
710
- const outputTokenDiff = (genAIUsageMetadata.candidatesTokenCount ?? 0) -
711
- usageMetadata.output_tokens;
712
- usageMetadata = {
713
- input_tokens: 0,
714
- output_tokens: outputTokenDiff,
715
- total_tokens: outputTokenDiff,
716
- };
717
- }
707
+ usageMetadata = {
708
+ input_tokens: response.usageMetadata.promptTokenCount ?? 0,
709
+ output_tokens: response.usageMetadata.candidatesTokenCount ?? 0,
710
+ total_tokens: response.usageMetadata.totalTokenCount ?? 0,
711
+ };
712
+ // Under the hood, LangChain combines the prompt tokens. Google returns the updated
713
+ // total each time, so we need to find the difference between the tokens.
714
+ const newPromptTokenCount = response.usageMetadata.promptTokenCount ?? 0;
715
+ usageMetadata.input_tokens = Math.max(0, newPromptTokenCount - prevPromptTokenCount);
716
+ prevPromptTokenCount = newPromptTokenCount;
717
+ const newCandidatesTokenCount = response.usageMetadata.candidatesTokenCount ?? 0;
718
+ usageMetadata.output_tokens = Math.max(0, newCandidatesTokenCount - prevCandidatesTokenCount);
719
+ prevCandidatesTokenCount = newCandidatesTokenCount;
720
+ const newTotalTokenCount = response.usageMetadata.totalTokenCount ?? 0;
721
+ usageMetadata.total_tokens = Math.max(0, newTotalTokenCount - prevTotalTokenCount);
722
+ prevTotalTokenCount = newTotalTokenCount;
718
723
  }
719
724
  const chunk = convertResponseContentToChatGenerationChunk(response, {
720
725
  usageMetadata,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/google-genai",
3
- "version": "0.2.16",
3
+ "version": "0.2.18",
4
4
  "description": "Google Generative AI integration for LangChain.js",
5
5
  "type": "module",
6
6
  "engines": {