@langchain/google-common 0.2.4 → 0.2.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.
@@ -144,6 +144,12 @@ class ChatGoogleBase extends chat_models_1.BaseChatModel {
144
144
  writable: true,
145
145
  value: void 0
146
146
  });
147
+ Object.defineProperty(this, "maxReasoningTokens", {
148
+ enumerable: true,
149
+ configurable: true,
150
+ writable: true,
151
+ value: void 0
152
+ });
147
153
  Object.defineProperty(this, "topP", {
148
154
  enumerable: true,
149
155
  configurable: true,
@@ -39,6 +39,7 @@ export declare abstract class ChatGoogleBase<AuthOptions> extends BaseChatModel<
39
39
  modelName: string;
40
40
  temperature: number;
41
41
  maxOutputTokens: number;
42
+ maxReasoningTokens: number;
42
43
  topP: number;
43
44
  topK: number;
44
45
  presencePenalty: number;
@@ -140,6 +140,12 @@ export class ChatGoogleBase extends BaseChatModel {
140
140
  writable: true,
141
141
  value: void 0
142
142
  });
143
+ Object.defineProperty(this, "maxReasoningTokens", {
144
+ enumerable: true,
145
+ configurable: true,
146
+ writable: true,
147
+ value: void 0
148
+ });
143
149
  Object.defineProperty(this, "topP", {
144
150
  enumerable: true,
145
151
  configurable: true,
@@ -114,17 +114,17 @@ class GoogleHostConnection extends GoogleConnection {
114
114
  writable: true,
115
115
  value: void 0
116
116
  });
117
- Object.defineProperty(this, "apiVersion", {
117
+ Object.defineProperty(this, "_apiVersion", {
118
118
  enumerable: true,
119
119
  configurable: true,
120
120
  writable: true,
121
- value: "v1"
121
+ value: void 0
122
122
  });
123
123
  this.caller = caller;
124
124
  this.platformType = fields?.platformType;
125
125
  this._endpoint = fields?.endpoint;
126
126
  this._location = fields?.location;
127
- this.apiVersion = fields?.apiVersion ?? this.apiVersion;
127
+ this._apiVersion = fields?.apiVersion;
128
128
  this.client = client;
129
129
  }
130
130
  get platform() {
@@ -133,6 +133,12 @@ class GoogleHostConnection extends GoogleConnection {
133
133
  get computedPlatformType() {
134
134
  return "gcp";
135
135
  }
136
+ get computedApiVersion() {
137
+ return "v1";
138
+ }
139
+ get apiVersion() {
140
+ return this._apiVersion ?? this.computedApiVersion;
141
+ }
136
142
  get location() {
137
143
  return this._location ?? this.computedLocation;
138
144
  }
@@ -238,6 +244,14 @@ class GoogleAIConnection extends GoogleHostConnection {
238
244
  return "gcp";
239
245
  }
240
246
  }
247
+ get computedApiVersion() {
248
+ switch (this.platform) {
249
+ case "gai":
250
+ return "v1beta";
251
+ default:
252
+ return "v1";
253
+ }
254
+ }
241
255
  get computedLocation() {
242
256
  switch (this.apiName) {
243
257
  case "google":
@@ -25,10 +25,12 @@ export declare abstract class GoogleHostConnection<CallOptions extends AsyncCall
25
25
  platformType: GooglePlatformType | undefined;
26
26
  _endpoint: string | undefined;
27
27
  _location: string | undefined;
28
- apiVersion: string;
28
+ _apiVersion: string | undefined;
29
29
  constructor(fields: GoogleConnectionParams<AuthOptions> | undefined, caller: AsyncCaller, client: GoogleAbstractedClient, streaming?: boolean);
30
30
  get platform(): GooglePlatformType;
31
31
  get computedPlatformType(): GooglePlatformType;
32
+ get computedApiVersion(): string;
33
+ get apiVersion(): string;
32
34
  get location(): string;
33
35
  get computedLocation(): string;
34
36
  get endpoint(): string;
@@ -52,6 +54,7 @@ export declare abstract class GoogleAIConnection<CallOptions extends AsyncCaller
52
54
  get api(): GoogleAIAPI;
53
55
  get isApiKey(): boolean;
54
56
  get computedPlatformType(): GooglePlatformType;
57
+ get computedApiVersion(): string;
55
58
  get computedLocation(): string;
56
59
  abstract buildUrlMethod(): Promise<string>;
57
60
  buildUrlGenerativeLanguage(): Promise<string>;
@@ -110,17 +110,17 @@ export class GoogleHostConnection extends GoogleConnection {
110
110
  writable: true,
111
111
  value: void 0
112
112
  });
113
- Object.defineProperty(this, "apiVersion", {
113
+ Object.defineProperty(this, "_apiVersion", {
114
114
  enumerable: true,
115
115
  configurable: true,
116
116
  writable: true,
117
- value: "v1"
117
+ value: void 0
118
118
  });
119
119
  this.caller = caller;
120
120
  this.platformType = fields?.platformType;
121
121
  this._endpoint = fields?.endpoint;
122
122
  this._location = fields?.location;
123
- this.apiVersion = fields?.apiVersion ?? this.apiVersion;
123
+ this._apiVersion = fields?.apiVersion;
124
124
  this.client = client;
125
125
  }
126
126
  get platform() {
@@ -129,6 +129,12 @@ export class GoogleHostConnection extends GoogleConnection {
129
129
  get computedPlatformType() {
130
130
  return "gcp";
131
131
  }
132
+ get computedApiVersion() {
133
+ return "v1";
134
+ }
135
+ get apiVersion() {
136
+ return this._apiVersion ?? this.computedApiVersion;
137
+ }
132
138
  get location() {
133
139
  return this._location ?? this.computedLocation;
134
140
  }
@@ -232,6 +238,14 @@ export class GoogleAIConnection extends GoogleHostConnection {
232
238
  return "gcp";
233
239
  }
234
240
  }
241
+ get computedApiVersion() {
242
+ switch (this.platform) {
243
+ case "gai":
244
+ return "v1beta";
245
+ default:
246
+ return "v1";
247
+ }
248
+ }
235
249
  get computedLocation() {
236
250
  switch (this.apiName) {
237
251
  case "google":
@@ -328,14 +328,8 @@ class AIStudioMediaBlob extends media_core_js_1.MediaBlob {
328
328
  }
329
329
  exports.AIStudioMediaBlob = AIStudioMediaBlob;
330
330
  class AIStudioFileUploadConnection extends GoogleMultipartUploadConnection {
331
- constructor() {
332
- super(...arguments);
333
- Object.defineProperty(this, "apiVersion", {
334
- enumerable: true,
335
- configurable: true,
336
- writable: true,
337
- value: "v1beta"
338
- });
331
+ get computedApiVersion() {
332
+ return "v1beta";
339
333
  }
340
334
  async buildUrl() {
341
335
  return `https://generativelanguage.googleapis.com/upload/${this.apiVersion}/files`;
@@ -357,15 +351,12 @@ class AIStudioFileDownloadConnection extends GoogleDownloadConnection {
357
351
  writable: true,
358
352
  value: void 0
359
353
  });
360
- Object.defineProperty(this, "apiVersion", {
361
- enumerable: true,
362
- configurable: true,
363
- writable: true,
364
- value: "v1beta"
365
- });
366
354
  this.method = fields.method;
367
355
  this.name = fields.name;
368
356
  }
357
+ get computedApiVersion() {
358
+ return "v1beta";
359
+ }
369
360
  buildMethod() {
370
361
  return this.method;
371
362
  }
@@ -166,7 +166,7 @@ export interface AIStudioFileConnectionParams {
166
166
  export interface AIStudioFileUploadConnectionParams<AuthOptions> extends GoogleUploadConnectionParams<AuthOptions>, AIStudioFileConnectionParams {
167
167
  }
168
168
  export declare class AIStudioFileUploadConnection<AuthOptions> extends GoogleMultipartUploadConnection<AsyncCallerCallOptions, AIStudioFileSaveResponse, AuthOptions> {
169
- apiVersion: string;
169
+ get computedApiVersion(): string;
170
170
  buildUrl(): Promise<string>;
171
171
  }
172
172
  export interface AIStudioFileDownloadConnectionParams<AuthOptions> extends AIStudioFileConnectionParams, GoogleConnectionParams<AuthOptions> {
@@ -176,8 +176,8 @@ export interface AIStudioFileDownloadConnectionParams<AuthOptions> extends AIStu
176
176
  export declare class AIStudioFileDownloadConnection<ResponseType extends GoogleResponse, AuthOptions> extends GoogleDownloadConnection<AsyncCallerCallOptions, ResponseType, AuthOptions> {
177
177
  method: GoogleAbstractedClientOpsMethod;
178
178
  name: string;
179
- apiVersion: string;
180
179
  constructor(fields: AIStudioFileDownloadConnectionParams<AuthOptions>, caller: AsyncCaller, client: GoogleAbstractedClient);
180
+ get computedApiVersion(): string;
181
181
  buildMethod(): GoogleAbstractedClientOpsMethod;
182
182
  buildUrl(): Promise<string>;
183
183
  }
@@ -315,14 +315,8 @@ export class AIStudioMediaBlob extends MediaBlob {
315
315
  }
316
316
  }
317
317
  export class AIStudioFileUploadConnection extends GoogleMultipartUploadConnection {
318
- constructor() {
319
- super(...arguments);
320
- Object.defineProperty(this, "apiVersion", {
321
- enumerable: true,
322
- configurable: true,
323
- writable: true,
324
- value: "v1beta"
325
- });
318
+ get computedApiVersion() {
319
+ return "v1beta";
326
320
  }
327
321
  async buildUrl() {
328
322
  return `https://generativelanguage.googleapis.com/upload/${this.apiVersion}/files`;
@@ -343,15 +337,12 @@ export class AIStudioFileDownloadConnection extends GoogleDownloadConnection {
343
337
  writable: true,
344
338
  value: void 0
345
339
  });
346
- Object.defineProperty(this, "apiVersion", {
347
- enumerable: true,
348
- configurable: true,
349
- writable: true,
350
- value: "v1beta"
351
- });
352
340
  this.method = fields.method;
353
341
  this.name = fields.name;
354
342
  }
343
+ get computedApiVersion() {
344
+ return "v1beta";
345
+ }
355
346
  buildMethod() {
356
347
  return this.method;
357
348
  }
@@ -13,8 +13,11 @@ export interface AnthropicMessageContentImage extends AnthropicMessageContentBas
13
13
  type: "image";
14
14
  source: {
15
15
  type: "base64" | string;
16
- media_type: string;
16
+ media_type?: string;
17
17
  data: string;
18
+ } | {
19
+ type: "url" | string;
20
+ url: string;
18
21
  };
19
22
  }
20
23
  export interface AnthropicMessageContentThinking extends AnthropicMessageContentBase {
@@ -22,6 +25,38 @@ export interface AnthropicMessageContentThinking extends AnthropicMessageContent
22
25
  thinking: string;
23
26
  signature: string;
24
27
  }
28
+ export interface AnthropicMessageContentDocument extends AnthropicMessageContentBase {
29
+ type: "document";
30
+ source: {
31
+ type: "base64" | "text" | string;
32
+ media_type?: "application/pdf" | "text/plain" | string;
33
+ data: string;
34
+ } | {
35
+ type: "url" | string;
36
+ url: string;
37
+ } | {
38
+ type: "content" | string;
39
+ content: {
40
+ type: "image" | string;
41
+ source: {
42
+ type: "base64" | string;
43
+ data: string;
44
+ media_type?: "image/jpeg" | "image/png" | "image/gif" | "image/webp" | string;
45
+ } | {
46
+ type: "url" | string;
47
+ url: string;
48
+ } | {
49
+ type: "text" | string;
50
+ text: string;
51
+ };
52
+ }[];
53
+ };
54
+ citations?: {
55
+ enabled?: boolean;
56
+ };
57
+ context?: string;
58
+ title?: string;
59
+ }
25
60
  export interface AnthropicMessageContentRedactedThinking extends AnthropicMessageContentBase {
26
61
  type: "redacted_thinking";
27
62
  data: string;
package/dist/types.d.ts CHANGED
@@ -85,6 +85,10 @@ export interface GoogleAISafetySetting {
85
85
  }
86
86
  export type GoogleAIResponseMimeType = "text/plain" | "application/json";
87
87
  export type GoogleAIModelModality = "TEXT" | "IMAGE" | "AUDIO" | string;
88
+ export interface GoogleThinkingConfig {
89
+ thinkingBudget?: number;
90
+ includeThoughts?: boolean;
91
+ }
88
92
  export interface GoogleAIModelParams {
89
93
  /** Model to use */
90
94
  model?: string;
@@ -97,8 +101,22 @@ export interface GoogleAIModelParams {
97
101
  temperature?: number;
98
102
  /**
99
103
  * Maximum number of tokens to generate in the completion.
104
+ * This may include reasoning tokens (for backwards compatibility).
100
105
  */
101
106
  maxOutputTokens?: number;
107
+ /**
108
+ * The maximum number of the output tokens that will be used
109
+ * for the "thinking" or "reasoning" stages.
110
+ */
111
+ maxReasoningTokens?: number;
112
+ /**
113
+ * An alias for "maxReasoningTokens"
114
+ */
115
+ thinkingBudget?: number;
116
+ /**
117
+ * An OpenAI compatible parameter that will map to "maxReasoningTokens"
118
+ */
119
+ reasoningEffort?: "low" | "medium" | "high";
102
120
  /**
103
121
  * Top-p changes how the model selects tokens for output.
104
122
  *
@@ -398,6 +416,7 @@ export interface GeminiGenerationConfig {
398
416
  responseLogprobs?: boolean;
399
417
  logprobs?: number;
400
418
  responseModalities?: GoogleAIModelModality[];
419
+ thinkingConfig?: GoogleThinkingConfig;
401
420
  }
402
421
  export interface GeminiRequest {
403
422
  contents?: GeminiContent[];
@@ -373,16 +373,221 @@ function getAnthropicAPI(config) {
373
373
  return undefined;
374
374
  }
375
375
  }
376
+ const anthropicContentConverter = {
377
+ providerName: "anthropic",
378
+ fromStandardTextBlock(block) {
379
+ return {
380
+ type: "text",
381
+ text: block.text,
382
+ ...("cache_control" in (block.metadata ?? {})
383
+ ? {
384
+ cache_control: block.metadata
385
+ .cache_control,
386
+ }
387
+ : {}),
388
+ };
389
+ },
390
+ fromStandardImageBlock(block) {
391
+ if (block.source_type === "url") {
392
+ const data = (0, messages_1.parseBase64DataUrl)({
393
+ dataUrl: block.url,
394
+ asTypedArray: false,
395
+ });
396
+ if (data) {
397
+ return {
398
+ type: "image",
399
+ source: {
400
+ type: "base64",
401
+ data: data.data,
402
+ media_type: data.mime_type,
403
+ },
404
+ ...("cache_control" in (block.metadata ?? {})
405
+ ? { cache_control: block.metadata.cache_control }
406
+ : {}),
407
+ };
408
+ }
409
+ else {
410
+ return {
411
+ type: "image",
412
+ source: {
413
+ type: "url",
414
+ url: block.url,
415
+ media_type: block.mime_type ?? "",
416
+ },
417
+ ...("cache_control" in (block.metadata ?? {})
418
+ ? { cache_control: block.metadata.cache_control }
419
+ : {}),
420
+ };
421
+ }
422
+ }
423
+ else {
424
+ if (block.source_type === "base64") {
425
+ return {
426
+ type: "image",
427
+ source: {
428
+ type: "base64",
429
+ data: block.data,
430
+ media_type: block.mime_type ?? "",
431
+ },
432
+ ...("cache_control" in (block.metadata ?? {})
433
+ ? { cache_control: block.metadata.cache_control }
434
+ : {}),
435
+ };
436
+ }
437
+ else {
438
+ throw new Error(`Unsupported image source type: ${block.source_type}`);
439
+ }
440
+ }
441
+ },
442
+ fromStandardFileBlock(block) {
443
+ const mime_type = (block.mime_type ?? "").split(";")[0];
444
+ if (block.source_type === "url") {
445
+ if (mime_type === "application/pdf" || mime_type === "") {
446
+ return {
447
+ type: "document",
448
+ source: {
449
+ type: "url",
450
+ url: block.url,
451
+ media_type: block.mime_type ?? "",
452
+ },
453
+ ...("cache_control" in (block.metadata ?? {})
454
+ ? {
455
+ cache_control: block.metadata
456
+ .cache_control,
457
+ }
458
+ : {}),
459
+ ...("citations" in (block.metadata ?? {})
460
+ ? {
461
+ citations: block.metadata.citations,
462
+ }
463
+ : {}),
464
+ ...("context" in (block.metadata ?? {})
465
+ ? { context: block.metadata.context }
466
+ : {}),
467
+ ...(block.metadata?.title ||
468
+ block.metadata?.filename ||
469
+ block.metadata?.name
470
+ ? {
471
+ title: (block.metadata?.title ||
472
+ block.metadata?.filename ||
473
+ block.metadata?.name),
474
+ }
475
+ : {}),
476
+ };
477
+ }
478
+ throw new Error(`Unsupported file mime type for file url source: ${block.mime_type}`);
479
+ }
480
+ else if (block.source_type === "text") {
481
+ if (mime_type === "text/plain" || mime_type === "") {
482
+ return {
483
+ type: "document",
484
+ source: {
485
+ type: "text",
486
+ data: block.text,
487
+ media_type: block.mime_type ?? "",
488
+ },
489
+ ...("cache_control" in (block.metadata ?? {})
490
+ ? {
491
+ cache_control: block.metadata
492
+ .cache_control,
493
+ }
494
+ : {}),
495
+ ...("citations" in (block.metadata ?? {})
496
+ ? {
497
+ citations: block.metadata.citations,
498
+ }
499
+ : {}),
500
+ ...("context" in (block.metadata ?? {})
501
+ ? { context: block.metadata.context }
502
+ : {}),
503
+ ...("title" in (block.metadata ?? {})
504
+ ? { title: block.metadata.title }
505
+ : {}),
506
+ };
507
+ }
508
+ else {
509
+ throw new Error(`Unsupported file mime type for file text source: ${block.mime_type}`);
510
+ }
511
+ }
512
+ else if (block.source_type === "base64") {
513
+ if (mime_type === "application/pdf" || mime_type === "") {
514
+ return {
515
+ type: "document",
516
+ source: {
517
+ type: "base64",
518
+ data: block.data,
519
+ media_type: "application/pdf",
520
+ },
521
+ ...("cache_control" in (block.metadata ?? {})
522
+ ? {
523
+ cache_control: block.metadata
524
+ .cache_control,
525
+ }
526
+ : {}),
527
+ ...("citations" in (block.metadata ?? {})
528
+ ? {
529
+ citations: block.metadata.citations,
530
+ }
531
+ : {}),
532
+ ...("context" in (block.metadata ?? {})
533
+ ? { context: block.metadata.context }
534
+ : {}),
535
+ ...("title" in (block.metadata ?? {})
536
+ ? { title: block.metadata.title }
537
+ : {}),
538
+ };
539
+ }
540
+ else if (["image/jpeg", "image/png", "image/gif", "image/webp"].includes(mime_type)) {
541
+ return {
542
+ type: "document",
543
+ source: {
544
+ type: "content",
545
+ content: [
546
+ {
547
+ type: "image",
548
+ source: {
549
+ type: "base64",
550
+ data: block.data,
551
+ media_type: mime_type,
552
+ },
553
+ },
554
+ ],
555
+ },
556
+ ...("cache_control" in (block.metadata ?? {})
557
+ ? {
558
+ cache_control: block.metadata
559
+ .cache_control,
560
+ }
561
+ : {}),
562
+ ...("citations" in (block.metadata ?? {})
563
+ ? {
564
+ citations: block.metadata.citations,
565
+ }
566
+ : {}),
567
+ ...("context" in (block.metadata ?? {})
568
+ ? { context: block.metadata.context }
569
+ : {}),
570
+ ...("title" in (block.metadata ?? {})
571
+ ? { title: block.metadata.title }
572
+ : {}),
573
+ };
574
+ }
575
+ else {
576
+ throw new Error(`Unsupported file mime type for file base64 source: ${block.mime_type}`);
577
+ }
578
+ }
579
+ else {
580
+ throw new Error(`Unsupported file source type: ${block.source_type}`);
581
+ }
582
+ },
583
+ };
376
584
  function contentToAnthropicContent(content) {
377
- const ret = [];
378
585
  const ca = typeof content === "string" ? [{ type: "text", text: content }] : content;
379
- ca.forEach((complex) => {
380
- const ac = contentComplexToAnthropicContent(complex);
381
- if (ac) {
382
- ret.push(ac);
383
- }
384
- });
385
- return ret;
586
+ return ca
587
+ .map((complex) => (0, messages_1.isDataContentBlock)(complex)
588
+ ? (0, messages_1.convertToProviderContentBlock)(complex, anthropicContentConverter)
589
+ : contentComplexToAnthropicContent(complex))
590
+ .filter(Boolean);
386
591
  }
387
592
  function toolCallToAnthropicContent(toolCall) {
388
593
  return {
@@ -439,6 +644,9 @@ function getAnthropicAPI(config) {
439
644
  return aiMessageToAnthropicMessage(base);
440
645
  case "tool":
441
646
  return toolMessageToAnthropicMessage(base);
647
+ case "system":
648
+ // System messages are handled in formatSystem()
649
+ return undefined;
442
650
  default:
443
651
  console.warn(`Unknown BaseMessage type: ${type}`, base);
444
652
  return undefined;
@@ -1,5 +1,5 @@
1
1
  import { ChatGenerationChunk, } from "@langchain/core/outputs";
2
- import { AIMessageChunk, } from "@langchain/core/messages";
2
+ import { AIMessageChunk, isDataContentBlock, convertToProviderContentBlock, parseBase64DataUrl, } from "@langchain/core/messages";
3
3
  export function getAnthropicAPI(config) {
4
4
  function partToString(part) {
5
5
  return "text" in part ? part.text : "";
@@ -370,16 +370,221 @@ export function getAnthropicAPI(config) {
370
370
  return undefined;
371
371
  }
372
372
  }
373
+ const anthropicContentConverter = {
374
+ providerName: "anthropic",
375
+ fromStandardTextBlock(block) {
376
+ return {
377
+ type: "text",
378
+ text: block.text,
379
+ ...("cache_control" in (block.metadata ?? {})
380
+ ? {
381
+ cache_control: block.metadata
382
+ .cache_control,
383
+ }
384
+ : {}),
385
+ };
386
+ },
387
+ fromStandardImageBlock(block) {
388
+ if (block.source_type === "url") {
389
+ const data = parseBase64DataUrl({
390
+ dataUrl: block.url,
391
+ asTypedArray: false,
392
+ });
393
+ if (data) {
394
+ return {
395
+ type: "image",
396
+ source: {
397
+ type: "base64",
398
+ data: data.data,
399
+ media_type: data.mime_type,
400
+ },
401
+ ...("cache_control" in (block.metadata ?? {})
402
+ ? { cache_control: block.metadata.cache_control }
403
+ : {}),
404
+ };
405
+ }
406
+ else {
407
+ return {
408
+ type: "image",
409
+ source: {
410
+ type: "url",
411
+ url: block.url,
412
+ media_type: block.mime_type ?? "",
413
+ },
414
+ ...("cache_control" in (block.metadata ?? {})
415
+ ? { cache_control: block.metadata.cache_control }
416
+ : {}),
417
+ };
418
+ }
419
+ }
420
+ else {
421
+ if (block.source_type === "base64") {
422
+ return {
423
+ type: "image",
424
+ source: {
425
+ type: "base64",
426
+ data: block.data,
427
+ media_type: block.mime_type ?? "",
428
+ },
429
+ ...("cache_control" in (block.metadata ?? {})
430
+ ? { cache_control: block.metadata.cache_control }
431
+ : {}),
432
+ };
433
+ }
434
+ else {
435
+ throw new Error(`Unsupported image source type: ${block.source_type}`);
436
+ }
437
+ }
438
+ },
439
+ fromStandardFileBlock(block) {
440
+ const mime_type = (block.mime_type ?? "").split(";")[0];
441
+ if (block.source_type === "url") {
442
+ if (mime_type === "application/pdf" || mime_type === "") {
443
+ return {
444
+ type: "document",
445
+ source: {
446
+ type: "url",
447
+ url: block.url,
448
+ media_type: block.mime_type ?? "",
449
+ },
450
+ ...("cache_control" in (block.metadata ?? {})
451
+ ? {
452
+ cache_control: block.metadata
453
+ .cache_control,
454
+ }
455
+ : {}),
456
+ ...("citations" in (block.metadata ?? {})
457
+ ? {
458
+ citations: block.metadata.citations,
459
+ }
460
+ : {}),
461
+ ...("context" in (block.metadata ?? {})
462
+ ? { context: block.metadata.context }
463
+ : {}),
464
+ ...(block.metadata?.title ||
465
+ block.metadata?.filename ||
466
+ block.metadata?.name
467
+ ? {
468
+ title: (block.metadata?.title ||
469
+ block.metadata?.filename ||
470
+ block.metadata?.name),
471
+ }
472
+ : {}),
473
+ };
474
+ }
475
+ throw new Error(`Unsupported file mime type for file url source: ${block.mime_type}`);
476
+ }
477
+ else if (block.source_type === "text") {
478
+ if (mime_type === "text/plain" || mime_type === "") {
479
+ return {
480
+ type: "document",
481
+ source: {
482
+ type: "text",
483
+ data: block.text,
484
+ media_type: block.mime_type ?? "",
485
+ },
486
+ ...("cache_control" in (block.metadata ?? {})
487
+ ? {
488
+ cache_control: block.metadata
489
+ .cache_control,
490
+ }
491
+ : {}),
492
+ ...("citations" in (block.metadata ?? {})
493
+ ? {
494
+ citations: block.metadata.citations,
495
+ }
496
+ : {}),
497
+ ...("context" in (block.metadata ?? {})
498
+ ? { context: block.metadata.context }
499
+ : {}),
500
+ ...("title" in (block.metadata ?? {})
501
+ ? { title: block.metadata.title }
502
+ : {}),
503
+ };
504
+ }
505
+ else {
506
+ throw new Error(`Unsupported file mime type for file text source: ${block.mime_type}`);
507
+ }
508
+ }
509
+ else if (block.source_type === "base64") {
510
+ if (mime_type === "application/pdf" || mime_type === "") {
511
+ return {
512
+ type: "document",
513
+ source: {
514
+ type: "base64",
515
+ data: block.data,
516
+ media_type: "application/pdf",
517
+ },
518
+ ...("cache_control" in (block.metadata ?? {})
519
+ ? {
520
+ cache_control: block.metadata
521
+ .cache_control,
522
+ }
523
+ : {}),
524
+ ...("citations" in (block.metadata ?? {})
525
+ ? {
526
+ citations: block.metadata.citations,
527
+ }
528
+ : {}),
529
+ ...("context" in (block.metadata ?? {})
530
+ ? { context: block.metadata.context }
531
+ : {}),
532
+ ...("title" in (block.metadata ?? {})
533
+ ? { title: block.metadata.title }
534
+ : {}),
535
+ };
536
+ }
537
+ else if (["image/jpeg", "image/png", "image/gif", "image/webp"].includes(mime_type)) {
538
+ return {
539
+ type: "document",
540
+ source: {
541
+ type: "content",
542
+ content: [
543
+ {
544
+ type: "image",
545
+ source: {
546
+ type: "base64",
547
+ data: block.data,
548
+ media_type: mime_type,
549
+ },
550
+ },
551
+ ],
552
+ },
553
+ ...("cache_control" in (block.metadata ?? {})
554
+ ? {
555
+ cache_control: block.metadata
556
+ .cache_control,
557
+ }
558
+ : {}),
559
+ ...("citations" in (block.metadata ?? {})
560
+ ? {
561
+ citations: block.metadata.citations,
562
+ }
563
+ : {}),
564
+ ...("context" in (block.metadata ?? {})
565
+ ? { context: block.metadata.context }
566
+ : {}),
567
+ ...("title" in (block.metadata ?? {})
568
+ ? { title: block.metadata.title }
569
+ : {}),
570
+ };
571
+ }
572
+ else {
573
+ throw new Error(`Unsupported file mime type for file base64 source: ${block.mime_type}`);
574
+ }
575
+ }
576
+ else {
577
+ throw new Error(`Unsupported file source type: ${block.source_type}`);
578
+ }
579
+ },
580
+ };
373
581
  function contentToAnthropicContent(content) {
374
- const ret = [];
375
582
  const ca = typeof content === "string" ? [{ type: "text", text: content }] : content;
376
- ca.forEach((complex) => {
377
- const ac = contentComplexToAnthropicContent(complex);
378
- if (ac) {
379
- ret.push(ac);
380
- }
381
- });
382
- return ret;
583
+ return ca
584
+ .map((complex) => isDataContentBlock(complex)
585
+ ? convertToProviderContentBlock(complex, anthropicContentConverter)
586
+ : contentComplexToAnthropicContent(complex))
587
+ .filter(Boolean);
383
588
  }
384
589
  function toolCallToAnthropicContent(toolCall) {
385
590
  return {
@@ -436,6 +641,9 @@ export function getAnthropicAPI(config) {
436
641
  return aiMessageToAnthropicMessage(base);
437
642
  case "tool":
438
643
  return toolMessageToAnthropicMessage(base);
644
+ case "system":
645
+ // System messages are handled in formatSystem()
646
+ return undefined;
439
647
  default:
440
648
  console.warn(`Unknown BaseMessage type: ${type}`, base);
441
649
  return undefined;
@@ -91,6 +91,22 @@ function convertToGeminiTools(tools) {
91
91
  return geminiTools;
92
92
  }
93
93
  exports.convertToGeminiTools = convertToGeminiTools;
94
+ function reasoningEffortToReasoningTokens(_modelName, effort) {
95
+ if (effort === undefined) {
96
+ return undefined;
97
+ }
98
+ const maxEffort = 24 * 1024; // Max for Gemini 2.5 Flash
99
+ switch (effort) {
100
+ case "low":
101
+ return maxEffort / 3;
102
+ case "medium":
103
+ return (2 * maxEffort) / 3;
104
+ case "high":
105
+ return maxEffort;
106
+ default:
107
+ return undefined;
108
+ }
109
+ }
94
110
  function copyAIModelParamsInto(params, options, target) {
95
111
  const ret = target || {};
96
112
  const model = options?.model ?? params?.model ?? target.model;
@@ -103,6 +119,16 @@ function copyAIModelParamsInto(params, options, target) {
103
119
  options?.maxOutputTokens ??
104
120
  params?.maxOutputTokens ??
105
121
  target.maxOutputTokens;
122
+ ret.maxReasoningTokens =
123
+ options?.maxReasoningTokens ??
124
+ params?.maxReasoningTokens ??
125
+ target?.maxReasoningTokens ??
126
+ options?.thinkingBudget ??
127
+ params?.thinkingBudget ??
128
+ target?.thinkingBudget ??
129
+ reasoningEffortToReasoningTokens(ret.modelName, params?.reasoningEffort) ??
130
+ reasoningEffortToReasoningTokens(ret.modelName, target?.reasoningEffort) ??
131
+ reasoningEffortToReasoningTokens(ret.modelName, options?.reasoningEffort);
106
132
  ret.topP = options?.topP ?? params?.topP ?? target.topP;
107
133
  ret.topK = options?.topK ?? params?.topK ?? target.topK;
108
134
  ret.presencePenalty =
@@ -86,6 +86,22 @@ export function convertToGeminiTools(tools) {
86
86
  });
87
87
  return geminiTools;
88
88
  }
89
+ function reasoningEffortToReasoningTokens(_modelName, effort) {
90
+ if (effort === undefined) {
91
+ return undefined;
92
+ }
93
+ const maxEffort = 24 * 1024; // Max for Gemini 2.5 Flash
94
+ switch (effort) {
95
+ case "low":
96
+ return maxEffort / 3;
97
+ case "medium":
98
+ return (2 * maxEffort) / 3;
99
+ case "high":
100
+ return maxEffort;
101
+ default:
102
+ return undefined;
103
+ }
104
+ }
89
105
  export function copyAIModelParamsInto(params, options, target) {
90
106
  const ret = target || {};
91
107
  const model = options?.model ?? params?.model ?? target.model;
@@ -98,6 +114,16 @@ export function copyAIModelParamsInto(params, options, target) {
98
114
  options?.maxOutputTokens ??
99
115
  params?.maxOutputTokens ??
100
116
  target.maxOutputTokens;
117
+ ret.maxReasoningTokens =
118
+ options?.maxReasoningTokens ??
119
+ params?.maxReasoningTokens ??
120
+ target?.maxReasoningTokens ??
121
+ options?.thinkingBudget ??
122
+ params?.thinkingBudget ??
123
+ target?.thinkingBudget ??
124
+ reasoningEffortToReasoningTokens(ret.modelName, params?.reasoningEffort) ??
125
+ reasoningEffortToReasoningTokens(ret.modelName, target?.reasoningEffort) ??
126
+ reasoningEffortToReasoningTokens(ret.modelName, options?.reasoningEffort);
101
127
  ret.topP = options?.topP ?? params?.topP ?? target.topP;
102
128
  ret.topK = options?.topK ?? params?.topK ?? target.topK;
103
129
  ret.presencePenalty =
@@ -198,6 +198,109 @@ function getGeminiAPI(config) {
198
198
  }
199
199
  throw new Error(`Invalid media content: ${JSON.stringify(content, null, 1)}`);
200
200
  }
201
+ const standardContentBlockConverter = {
202
+ providerName: "Google Gemini",
203
+ fromStandardTextBlock(block) {
204
+ return {
205
+ text: block.text,
206
+ };
207
+ },
208
+ fromStandardImageBlock(block) {
209
+ if (block.source_type === "url") {
210
+ const data = (0, messages_1.parseBase64DataUrl)({ dataUrl: block.url });
211
+ if (data) {
212
+ return {
213
+ inlineData: {
214
+ mimeType: data.mime_type,
215
+ data: data.data,
216
+ },
217
+ };
218
+ }
219
+ else {
220
+ return {
221
+ fileData: {
222
+ mimeType: block.mime_type ?? "",
223
+ fileUri: block.url,
224
+ },
225
+ };
226
+ }
227
+ }
228
+ if (block.source_type === "base64") {
229
+ return {
230
+ inlineData: {
231
+ mimeType: block.mime_type ?? "",
232
+ data: block.data,
233
+ },
234
+ };
235
+ }
236
+ throw new Error(`Unsupported source type: ${block.source_type}`);
237
+ },
238
+ fromStandardAudioBlock(block) {
239
+ if (block.source_type === "url") {
240
+ const data = (0, messages_1.parseBase64DataUrl)({ dataUrl: block.url });
241
+ if (data) {
242
+ return {
243
+ inlineData: {
244
+ mimeType: data.mime_type,
245
+ data: data.data,
246
+ },
247
+ };
248
+ }
249
+ else {
250
+ return {
251
+ fileData: {
252
+ mimeType: block.mime_type ?? "",
253
+ fileUri: block.url,
254
+ },
255
+ };
256
+ }
257
+ }
258
+ if (block.source_type === "base64") {
259
+ return {
260
+ inlineData: {
261
+ mimeType: block.mime_type ?? "",
262
+ data: block.data,
263
+ },
264
+ };
265
+ }
266
+ throw new Error(`Unsupported source type: ${block.source_type}`);
267
+ },
268
+ fromStandardFileBlock(block) {
269
+ if (block.source_type === "text") {
270
+ return {
271
+ text: block.text,
272
+ };
273
+ }
274
+ if (block.source_type === "url") {
275
+ const data = (0, messages_1.parseBase64DataUrl)({ dataUrl: block.url });
276
+ if (data) {
277
+ return {
278
+ inlineData: {
279
+ mimeType: data.mime_type,
280
+ data: data.data,
281
+ },
282
+ };
283
+ }
284
+ else {
285
+ return {
286
+ fileData: {
287
+ mimeType: block.mime_type ?? "",
288
+ fileUri: block.url,
289
+ },
290
+ };
291
+ }
292
+ }
293
+ if (block.source_type === "base64") {
294
+ return {
295
+ inlineData: {
296
+ mimeType: block.mime_type ?? "",
297
+ data: block.data,
298
+ },
299
+ };
300
+ }
301
+ throw new Error(`Unsupported source type: ${block.source_type}`);
302
+ },
303
+ };
201
304
  async function messageContentComplexToPart(content) {
202
305
  switch (content.type) {
203
306
  case "text":
@@ -219,7 +322,9 @@ function getGeminiAPI(config) {
219
322
  throw new Error(`Cannot coerce "${content.type}" message part into a string.`);
220
323
  }
221
324
  async function messageContentComplexToParts(content) {
222
- const contents = content.map(messageContentComplexToPart);
325
+ const contents = content.map((m) => (0, messages_1.isDataContentBlock)(m)
326
+ ? (0, messages_1.convertToProviderContentBlock)(m, standardContentBlockConverter)
327
+ : messageContentComplexToPart(m));
223
328
  return Promise.all(contents);
224
329
  }
225
330
  async function messageContentToParts(content) {
@@ -546,12 +651,9 @@ function getGeminiAPI(config) {
546
651
  if (!data) {
547
652
  return {};
548
653
  }
549
- return {
550
- usage_metadata: {
551
- prompt_token_count: data.usageMetadata?.promptTokenCount,
552
- candidates_token_count: data.usageMetadata?.candidatesTokenCount,
553
- total_token_count: data.usageMetadata?.totalTokenCount,
554
- },
654
+ const finish_reason = data.candidates[0]?.finishReason;
655
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
656
+ const ret = {
555
657
  safety_ratings: data.candidates[0]?.safetyRatings?.map((rating) => ({
556
658
  category: rating.category,
557
659
  probability: rating.probability,
@@ -561,11 +663,21 @@ function getGeminiAPI(config) {
561
663
  })),
562
664
  citation_metadata: data.candidates[0]?.citationMetadata,
563
665
  grounding_metadata: data.candidates[0]?.groundingMetadata,
564
- finish_reason: data.candidates[0]?.finishReason,
666
+ finish_reason,
565
667
  finish_message: data.candidates[0]?.finishMessage,
566
668
  avgLogprobs: data.candidates[0]?.avgLogprobs,
567
669
  logprobs: candidateToLogprobs(data.candidates[0]),
568
670
  };
671
+ // Only add the usage_metadata on the last chunk
672
+ // sent while streaming (see issue 8102).
673
+ if (typeof finish_reason === "string") {
674
+ ret.usage_metadata = {
675
+ prompt_token_count: data.usageMetadata?.promptTokenCount,
676
+ candidates_token_count: data.usageMetadata?.candidatesTokenCount,
677
+ total_token_count: data.usageMetadata?.totalTokenCount,
678
+ };
679
+ }
680
+ return ret;
569
681
  }
570
682
  function responseToChatGeneration(response) {
571
683
  return new outputs_1.ChatGenerationChunk({
@@ -951,6 +1063,13 @@ function getGeminiAPI(config) {
951
1063
  ret.logprobs = parameters.topLogprobs;
952
1064
  }
953
1065
  }
1066
+ // Add thinking configuration if explicitly set
1067
+ if (typeof parameters.maxReasoningTokens !== "undefined") {
1068
+ ret.thinkingConfig = {
1069
+ thinkingBudget: parameters.maxReasoningTokens,
1070
+ includeThoughts: true,
1071
+ };
1072
+ }
954
1073
  // Remove any undefined properties, so we don't send them
955
1074
  let attribute;
956
1075
  for (attribute in ret) {
@@ -1113,6 +1232,16 @@ function validateGeminiParams(params) {
1113
1232
  if (params.maxOutputTokens && params.maxOutputTokens < 0) {
1114
1233
  throw new Error("`maxOutputTokens` must be a positive integer");
1115
1234
  }
1235
+ if (typeof params.maxReasoningTokens !== "undefined") {
1236
+ if (params.maxReasoningTokens < 0) {
1237
+ throw new Error("`maxReasoningTokens` must be non-negative integer");
1238
+ }
1239
+ if (typeof params.maxOutputTokens !== "undefined") {
1240
+ if (params.maxReasoningTokens >= params.maxOutputTokens) {
1241
+ throw new Error("`maxOutputTokens` must be greater than `maxReasoningTokens`");
1242
+ }
1243
+ }
1244
+ }
1116
1245
  if (params.temperature &&
1117
1246
  (params.temperature < 0 || params.temperature > 2)) {
1118
1247
  throw new Error("`temperature` must be in the range of [0.0,2.0]");
@@ -1,5 +1,5 @@
1
1
  import { v4 as uuidv4 } from "uuid";
2
- import { AIMessage, AIMessageChunk, isAIMessage, } from "@langchain/core/messages";
2
+ import { AIMessage, AIMessageChunk, isAIMessage, parseBase64DataUrl, isDataContentBlock, convertToProviderContentBlock, } from "@langchain/core/messages";
3
3
  import { ChatGenerationChunk, } from "@langchain/core/outputs";
4
4
  import { isLangChainTool } from "@langchain/core/utils/function_calling";
5
5
  import { concat } from "@langchain/core/utils/stream";
@@ -193,6 +193,109 @@ export function getGeminiAPI(config) {
193
193
  }
194
194
  throw new Error(`Invalid media content: ${JSON.stringify(content, null, 1)}`);
195
195
  }
196
+ const standardContentBlockConverter = {
197
+ providerName: "Google Gemini",
198
+ fromStandardTextBlock(block) {
199
+ return {
200
+ text: block.text,
201
+ };
202
+ },
203
+ fromStandardImageBlock(block) {
204
+ if (block.source_type === "url") {
205
+ const data = parseBase64DataUrl({ dataUrl: block.url });
206
+ if (data) {
207
+ return {
208
+ inlineData: {
209
+ mimeType: data.mime_type,
210
+ data: data.data,
211
+ },
212
+ };
213
+ }
214
+ else {
215
+ return {
216
+ fileData: {
217
+ mimeType: block.mime_type ?? "",
218
+ fileUri: block.url,
219
+ },
220
+ };
221
+ }
222
+ }
223
+ if (block.source_type === "base64") {
224
+ return {
225
+ inlineData: {
226
+ mimeType: block.mime_type ?? "",
227
+ data: block.data,
228
+ },
229
+ };
230
+ }
231
+ throw new Error(`Unsupported source type: ${block.source_type}`);
232
+ },
233
+ fromStandardAudioBlock(block) {
234
+ if (block.source_type === "url") {
235
+ const data = parseBase64DataUrl({ dataUrl: block.url });
236
+ if (data) {
237
+ return {
238
+ inlineData: {
239
+ mimeType: data.mime_type,
240
+ data: data.data,
241
+ },
242
+ };
243
+ }
244
+ else {
245
+ return {
246
+ fileData: {
247
+ mimeType: block.mime_type ?? "",
248
+ fileUri: block.url,
249
+ },
250
+ };
251
+ }
252
+ }
253
+ if (block.source_type === "base64") {
254
+ return {
255
+ inlineData: {
256
+ mimeType: block.mime_type ?? "",
257
+ data: block.data,
258
+ },
259
+ };
260
+ }
261
+ throw new Error(`Unsupported source type: ${block.source_type}`);
262
+ },
263
+ fromStandardFileBlock(block) {
264
+ if (block.source_type === "text") {
265
+ return {
266
+ text: block.text,
267
+ };
268
+ }
269
+ if (block.source_type === "url") {
270
+ const data = parseBase64DataUrl({ dataUrl: block.url });
271
+ if (data) {
272
+ return {
273
+ inlineData: {
274
+ mimeType: data.mime_type,
275
+ data: data.data,
276
+ },
277
+ };
278
+ }
279
+ else {
280
+ return {
281
+ fileData: {
282
+ mimeType: block.mime_type ?? "",
283
+ fileUri: block.url,
284
+ },
285
+ };
286
+ }
287
+ }
288
+ if (block.source_type === "base64") {
289
+ return {
290
+ inlineData: {
291
+ mimeType: block.mime_type ?? "",
292
+ data: block.data,
293
+ },
294
+ };
295
+ }
296
+ throw new Error(`Unsupported source type: ${block.source_type}`);
297
+ },
298
+ };
196
299
  async function messageContentComplexToPart(content) {
197
300
  switch (content.type) {
198
301
  case "text":
@@ -214,7 +317,9 @@ export function getGeminiAPI(config) {
214
317
  throw new Error(`Cannot coerce "${content.type}" message part into a string.`);
215
318
  }
216
319
  async function messageContentComplexToParts(content) {
217
- const contents = content.map(messageContentComplexToPart);
320
+ const contents = content.map((m) => isDataContentBlock(m)
321
+ ? convertToProviderContentBlock(m, standardContentBlockConverter)
322
+ : messageContentComplexToPart(m));
218
323
  return Promise.all(contents);
219
324
  }
220
325
  async function messageContentToParts(content) {
@@ -541,12 +646,9 @@ export function getGeminiAPI(config) {
541
646
  if (!data) {
542
647
  return {};
543
648
  }
544
- return {
545
- usage_metadata: {
546
- prompt_token_count: data.usageMetadata?.promptTokenCount,
547
- candidates_token_count: data.usageMetadata?.candidatesTokenCount,
548
- total_token_count: data.usageMetadata?.totalTokenCount,
549
- },
649
+ const finish_reason = data.candidates[0]?.finishReason;
650
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
651
+ const ret = {
550
652
  safety_ratings: data.candidates[0]?.safetyRatings?.map((rating) => ({
551
653
  category: rating.category,
552
654
  probability: rating.probability,
@@ -556,11 +658,21 @@ export function getGeminiAPI(config) {
556
658
  })),
557
659
  citation_metadata: data.candidates[0]?.citationMetadata,
558
660
  grounding_metadata: data.candidates[0]?.groundingMetadata,
559
- finish_reason: data.candidates[0]?.finishReason,
661
+ finish_reason,
560
662
  finish_message: data.candidates[0]?.finishMessage,
561
663
  avgLogprobs: data.candidates[0]?.avgLogprobs,
562
664
  logprobs: candidateToLogprobs(data.candidates[0]),
563
665
  };
666
+ // Only add the usage_metadata on the last chunk
667
+ // sent while streaming (see issue 8102).
668
+ if (typeof finish_reason === "string") {
669
+ ret.usage_metadata = {
670
+ prompt_token_count: data.usageMetadata?.promptTokenCount,
671
+ candidates_token_count: data.usageMetadata?.candidatesTokenCount,
672
+ total_token_count: data.usageMetadata?.totalTokenCount,
673
+ };
674
+ }
675
+ return ret;
564
676
  }
565
677
  function responseToChatGeneration(response) {
566
678
  return new ChatGenerationChunk({
@@ -946,6 +1058,13 @@ export function getGeminiAPI(config) {
946
1058
  ret.logprobs = parameters.topLogprobs;
947
1059
  }
948
1060
  }
1061
+ // Add thinking configuration if explicitly set
1062
+ if (typeof parameters.maxReasoningTokens !== "undefined") {
1063
+ ret.thinkingConfig = {
1064
+ thinkingBudget: parameters.maxReasoningTokens,
1065
+ includeThoughts: true,
1066
+ };
1067
+ }
949
1068
  // Remove any undefined properties, so we don't send them
950
1069
  let attribute;
951
1070
  for (attribute in ret) {
@@ -1107,6 +1226,16 @@ export function validateGeminiParams(params) {
1107
1226
  if (params.maxOutputTokens && params.maxOutputTokens < 0) {
1108
1227
  throw new Error("`maxOutputTokens` must be a positive integer");
1109
1228
  }
1229
+ if (typeof params.maxReasoningTokens !== "undefined") {
1230
+ if (params.maxReasoningTokens < 0) {
1231
+ throw new Error("`maxReasoningTokens` must be non-negative integer");
1232
+ }
1233
+ if (typeof params.maxOutputTokens !== "undefined") {
1234
+ if (params.maxReasoningTokens >= params.maxOutputTokens) {
1235
+ throw new Error("`maxOutputTokens` must be greater than `maxReasoningTokens`");
1236
+ }
1237
+ }
1238
+ }
1110
1239
  if (params.temperature &&
1111
1240
  (params.temperature < 0 || params.temperature > 2)) {
1112
1241
  throw new Error("`temperature` must be in the range of [0.0,2.0]");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/google-common",
3
- "version": "0.2.4",
3
+ "version": "0.2.6",
4
4
  "description": "Core types and classes for Google services.",
5
5
  "type": "module",
6
6
  "engines": {
@@ -36,11 +36,11 @@
36
36
  "zod-to-json-schema": "^3.22.4"
37
37
  },
38
38
  "peerDependencies": {
39
- "@langchain/core": ">=0.2.21 <0.4.0"
39
+ "@langchain/core": ">=0.3.48 <0.4.0"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@jest/globals": "^29.5.0",
43
- "@langchain/core": "0.3.44",
43
+ "@langchain/core": "0.3.53",
44
44
  "@langchain/scripts": ">=0.1.0 <0.2.0",
45
45
  "@swc/core": "^1.3.90",
46
46
  "@swc/jest": "^0.2.29",
@@ -58,7 +58,7 @@
58
58
  "jest": "^29.5.0",
59
59
  "jest-environment-node": "^29.6.4",
60
60
  "prettier": "^2.8.3",
61
- "release-it": "^17.6.0",
61
+ "release-it": "^18.1.2",
62
62
  "rollup": "^4.5.2",
63
63
  "ts-jest": "^29.1.0",
64
64
  "typescript": "<5.2.0",