@langchain/google-common 0.2.7 → 0.2.9

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.
@@ -162,6 +162,12 @@ class ChatGoogleBase extends chat_models_1.BaseChatModel {
162
162
  writable: true,
163
163
  value: void 0
164
164
  });
165
+ Object.defineProperty(this, "seed", {
166
+ enumerable: true,
167
+ configurable: true,
168
+ writable: true,
169
+ value: void 0
170
+ });
165
171
  Object.defineProperty(this, "presencePenalty", {
166
172
  enumerable: true,
167
173
  configurable: true,
@@ -42,6 +42,7 @@ export declare abstract class ChatGoogleBase<AuthOptions> extends BaseChatModel<
42
42
  maxReasoningTokens: number;
43
43
  topP: number;
44
44
  topK: number;
45
+ seed: number;
45
46
  presencePenalty: number;
46
47
  frequencyPenalty: number;
47
48
  stopSequences: string[];
@@ -158,6 +158,12 @@ export class ChatGoogleBase extends BaseChatModel {
158
158
  writable: true,
159
159
  value: void 0
160
160
  });
161
+ Object.defineProperty(this, "seed", {
162
+ enumerable: true,
163
+ configurable: true,
164
+ writable: true,
165
+ value: void 0
166
+ });
161
167
  Object.defineProperty(this, "presencePenalty", {
162
168
  enumerable: true,
163
169
  configurable: true,
@@ -121,12 +121,24 @@ class GoogleHostConnection extends GoogleConnection {
121
121
  value: void 0
122
122
  });
123
123
  this.caller = caller;
124
- this.platformType = fields?.platformType;
124
+ this.platformType = this.fieldPlatformType(fields);
125
125
  this._endpoint = fields?.endpoint;
126
126
  this._location = fields?.location;
127
127
  this._apiVersion = fields?.apiVersion;
128
128
  this.client = client;
129
129
  }
130
+ fieldPlatformType(fields) {
131
+ if (typeof fields === "undefined") {
132
+ return undefined;
133
+ }
134
+ if (typeof fields.platformType !== "undefined") {
135
+ return fields.platformType;
136
+ }
137
+ if (fields.vertexai === true) {
138
+ return "gcp";
139
+ }
140
+ return undefined;
141
+ }
130
142
  get platform() {
131
143
  return this.platformType ?? this.computedPlatformType;
132
144
  }
@@ -149,7 +161,12 @@ class GoogleHostConnection extends GoogleConnection {
149
161
  return this._endpoint ?? this.computedEndpoint;
150
162
  }
151
163
  get computedEndpoint() {
152
- return `${this.location}-aiplatform.googleapis.com`;
164
+ if (this.location === "global") {
165
+ return "aiplatform.googleapis.com";
166
+ }
167
+ else {
168
+ return `${this.location}-aiplatform.googleapis.com`;
169
+ }
153
170
  }
154
171
  buildMethod() {
155
172
  return "POST";
@@ -233,6 +250,16 @@ class GoogleAIConnection extends GoogleHostConnection {
233
250
  get isApiKey() {
234
251
  return this.client.clientType === "apiKey";
235
252
  }
253
+ fieldPlatformType(fields) {
254
+ const ret = super.fieldPlatformType(fields);
255
+ if (typeof ret !== "undefined") {
256
+ return ret;
257
+ }
258
+ if (fields?.vertexai === false) {
259
+ return "gai";
260
+ }
261
+ return undefined;
262
+ }
236
263
  get computedPlatformType() {
237
264
  // This is not a completely correct assumption, since GCP can
238
265
  // have an API Key. But if so, then people need to set the platform
@@ -27,6 +27,7 @@ export declare abstract class GoogleHostConnection<CallOptions extends AsyncCall
27
27
  _location: string | undefined;
28
28
  _apiVersion: string | undefined;
29
29
  constructor(fields: GoogleConnectionParams<AuthOptions> | undefined, caller: AsyncCaller, client: GoogleAbstractedClient, streaming?: boolean);
30
+ fieldPlatformType(fields: GoogleConnectionParams<any> | undefined): GooglePlatformType | undefined;
30
31
  get platform(): GooglePlatformType;
31
32
  get computedPlatformType(): GooglePlatformType;
32
33
  get computedApiVersion(): string;
@@ -53,6 +54,7 @@ export declare abstract class GoogleAIConnection<CallOptions extends AsyncCaller
53
54
  get apiName(): string;
54
55
  get api(): GoogleAIAPI;
55
56
  get isApiKey(): boolean;
57
+ fieldPlatformType(fields: GoogleConnectionParams<any> | undefined): GooglePlatformType | undefined;
56
58
  get computedPlatformType(): GooglePlatformType;
57
59
  get computedApiVersion(): string;
58
60
  get computedLocation(): string;
@@ -117,12 +117,24 @@ export class GoogleHostConnection extends GoogleConnection {
117
117
  value: void 0
118
118
  });
119
119
  this.caller = caller;
120
- this.platformType = fields?.platformType;
120
+ this.platformType = this.fieldPlatformType(fields);
121
121
  this._endpoint = fields?.endpoint;
122
122
  this._location = fields?.location;
123
123
  this._apiVersion = fields?.apiVersion;
124
124
  this.client = client;
125
125
  }
126
+ fieldPlatformType(fields) {
127
+ if (typeof fields === "undefined") {
128
+ return undefined;
129
+ }
130
+ if (typeof fields.platformType !== "undefined") {
131
+ return fields.platformType;
132
+ }
133
+ if (fields.vertexai === true) {
134
+ return "gcp";
135
+ }
136
+ return undefined;
137
+ }
126
138
  get platform() {
127
139
  return this.platformType ?? this.computedPlatformType;
128
140
  }
@@ -145,7 +157,12 @@ export class GoogleHostConnection extends GoogleConnection {
145
157
  return this._endpoint ?? this.computedEndpoint;
146
158
  }
147
159
  get computedEndpoint() {
148
- return `${this.location}-aiplatform.googleapis.com`;
160
+ if (this.location === "global") {
161
+ return "aiplatform.googleapis.com";
162
+ }
163
+ else {
164
+ return `${this.location}-aiplatform.googleapis.com`;
165
+ }
149
166
  }
150
167
  buildMethod() {
151
168
  return "POST";
@@ -227,6 +244,16 @@ export class GoogleAIConnection extends GoogleHostConnection {
227
244
  get isApiKey() {
228
245
  return this.client.clientType === "apiKey";
229
246
  }
247
+ fieldPlatformType(fields) {
248
+ const ret = super.fieldPlatformType(fields);
249
+ if (typeof ret !== "undefined") {
250
+ return ret;
251
+ }
252
+ if (fields?.vertexai === false) {
253
+ return "gai";
254
+ }
255
+ return undefined;
256
+ }
230
257
  get computedPlatformType() {
231
258
  // This is not a completely correct assumption, since GCP can
232
259
  // have an API Key. But if so, then people need to set the platform
package/dist/types.d.ts CHANGED
@@ -36,6 +36,11 @@ export interface GoogleConnectionParams<AuthOptions> extends GoogleClientParams<
36
36
  * the "platform" getter.
37
37
  */
38
38
  platformType?: GooglePlatformType;
39
+ /**
40
+ * For compatibility with Google's libraries, should this use Vertex?
41
+ * The "platformType" parmeter takes precedence.
42
+ */
43
+ vertexai?: boolean;
39
44
  }
40
45
  export declare const GoogleAISafetyCategory: {
41
46
  readonly Harassment: "HARM_CATEGORY_HARASSMENT";
@@ -137,6 +142,10 @@ export interface GoogleAIModelParams {
137
142
  * among the 3 most probable tokens (using temperature).
138
143
  */
139
144
  topK?: number;
145
+ /**
146
+ * Seed used in decoding. If not set, the request uses a randomly generated seed.
147
+ */
148
+ seed?: number;
140
149
  /**
141
150
  * Presence penalty applied to the next token's logprobs
142
151
  * if the token has already been seen in the response.
@@ -410,6 +419,7 @@ export interface GeminiGenerationConfig {
410
419
  temperature?: number;
411
420
  topP?: number;
412
421
  topK?: number;
422
+ seed?: number;
413
423
  presencePenalty?: number;
414
424
  frequencyPenalty?: number;
415
425
  responseMimeType?: GoogleAIResponseMimeType;
@@ -495,6 +505,7 @@ export interface GoogleAISafetyParams {
495
505
  export type GeminiJsonSchema = Record<string, unknown> & {
496
506
  properties?: Record<string, GeminiJsonSchema>;
497
507
  type: GeminiFunctionSchemaType;
508
+ nullable?: boolean;
498
509
  };
499
510
  export interface GeminiJsonSchemaDirty extends GeminiJsonSchema {
500
511
  items?: GeminiJsonSchemaDirty;
@@ -131,6 +131,7 @@ function copyAIModelParamsInto(params, options, target) {
131
131
  reasoningEffortToReasoningTokens(ret.modelName, options?.reasoningEffort);
132
132
  ret.topP = options?.topP ?? params?.topP ?? target.topP;
133
133
  ret.topK = options?.topK ?? params?.topK ?? target.topK;
134
+ ret.seed = options?.seed ?? params?.seed ?? target.seed;
134
135
  ret.presencePenalty =
135
136
  options?.presencePenalty ??
136
137
  params?.presencePenalty ??
@@ -126,6 +126,7 @@ export function copyAIModelParamsInto(params, options, target) {
126
126
  reasoningEffortToReasoningTokens(ret.modelName, options?.reasoningEffort);
127
127
  ret.topP = options?.topP ?? params?.topP ?? target.topP;
128
128
  ret.topK = options?.topK ?? params?.topK ?? target.topK;
129
+ ret.seed = options?.seed ?? params?.seed ?? target.seed;
129
130
  ret.presencePenalty =
130
131
  options?.presencePenalty ??
131
132
  params?.presencePenalty ??
@@ -659,6 +659,9 @@ function getGeminiAPI(config) {
659
659
  const total_tokens = usageMetadata.totalTokenCount ?? input_tokens + output_tokens;
660
660
  const input_token_details = {};
661
661
  addModalityCounts(usageMetadata.promptTokensDetails, input_token_details);
662
+ if (typeof usageMetadata?.cachedContentTokenCount === "number") {
663
+ input_token_details.cache_read = usageMetadata.cachedContentTokenCount;
664
+ }
662
665
  const output_token_details = {};
663
666
  addModalityCounts(usageMetadata?.candidatesTokensDetails, output_token_details);
664
667
  if (typeof usageMetadata?.thoughtsTokenCount === "number") {
@@ -1072,6 +1075,7 @@ function getGeminiAPI(config) {
1072
1075
  temperature: parameters.temperature,
1073
1076
  topK: parameters.topK,
1074
1077
  topP: parameters.topP,
1078
+ seed: parameters.seed,
1075
1079
  presencePenalty: parameters.presencePenalty,
1076
1080
  frequencyPenalty: parameters.frequencyPenalty,
1077
1081
  maxOutputTokens: parameters.maxOutputTokens,
@@ -1088,8 +1092,8 @@ function getGeminiAPI(config) {
1088
1092
  }
1089
1093
  }
1090
1094
  // Add thinking configuration if explicitly set
1091
- if (typeof parameters.maxReasoningTokens !== "undefined" &&
1092
- parameters.maxReasoningTokens !== 0) {
1095
+ // Note that you cannot have thinkingBudget set to 0 and includeThoughts true
1096
+ if (typeof parameters.maxReasoningTokens !== "undefined") {
1093
1097
  ret.thinkingConfig = {
1094
1098
  thinkingBudget: parameters.maxReasoningTokens,
1095
1099
  // TODO: Expose this configuration to the user once google fully supports it
@@ -654,6 +654,9 @@ export function getGeminiAPI(config) {
654
654
  const total_tokens = usageMetadata.totalTokenCount ?? input_tokens + output_tokens;
655
655
  const input_token_details = {};
656
656
  addModalityCounts(usageMetadata.promptTokensDetails, input_token_details);
657
+ if (typeof usageMetadata?.cachedContentTokenCount === "number") {
658
+ input_token_details.cache_read = usageMetadata.cachedContentTokenCount;
659
+ }
657
660
  const output_token_details = {};
658
661
  addModalityCounts(usageMetadata?.candidatesTokensDetails, output_token_details);
659
662
  if (typeof usageMetadata?.thoughtsTokenCount === "number") {
@@ -1067,6 +1070,7 @@ export function getGeminiAPI(config) {
1067
1070
  temperature: parameters.temperature,
1068
1071
  topK: parameters.topK,
1069
1072
  topP: parameters.topP,
1073
+ seed: parameters.seed,
1070
1074
  presencePenalty: parameters.presencePenalty,
1071
1075
  frequencyPenalty: parameters.frequencyPenalty,
1072
1076
  maxOutputTokens: parameters.maxOutputTokens,
@@ -1083,8 +1087,8 @@ export function getGeminiAPI(config) {
1083
1087
  }
1084
1088
  }
1085
1089
  // Add thinking configuration if explicitly set
1086
- if (typeof parameters.maxReasoningTokens !== "undefined" &&
1087
- parameters.maxReasoningTokens !== 0) {
1090
+ // Note that you cannot have thinkingBudget set to 0 and includeThoughts true
1091
+ if (typeof parameters.maxReasoningTokens !== "undefined") {
1088
1092
  ret.thinkingConfig = {
1089
1093
  thinkingBudget: parameters.maxReasoningTokens,
1090
1094
  // TODO: Expose this configuration to the user once google fully supports it
@@ -12,6 +12,31 @@ obj) {
12
12
  if ("additionalProperties" in newObj) {
13
13
  delete newObj.additionalProperties;
14
14
  }
15
+ if (Array.isArray(obj.type)) {
16
+ const len = obj.type.length;
17
+ const nullIndex = obj.type.indexOf("null");
18
+ if (len === 2 && nullIndex >= 0) {
19
+ // There are only two values set for the type, and one of them is "null".
20
+ // Set the type to the other one and set nullable to true.
21
+ const typeIndex = nullIndex === 0 ? 1 : 0;
22
+ newObj.type = obj.type[typeIndex];
23
+ newObj.nullable = true;
24
+ }
25
+ else if (len === 1 && nullIndex === 0) {
26
+ // This is nullable only without a type, which doesn't
27
+ // make sense for Gemini
28
+ throw new Error("zod_to_gemini_parameters: Gemini cannot handle null type");
29
+ }
30
+ else if (len === 1) {
31
+ // Although an array, it has only one value.
32
+ // So set it to the string to match what Gemini expects.
33
+ newObj.type = obj?.type[0];
34
+ }
35
+ else {
36
+ // Anything else could be a union type, so reject it.
37
+ throw new Error("zod_to_gemini_parameters: Gemini cannot handle union types");
38
+ }
39
+ }
15
40
  for (const key in newObj) {
16
41
  if (key in newObj) {
17
42
  if (Array.isArray(newObj[key])) {
@@ -30,6 +55,8 @@ exports.removeAdditionalProperties = removeAdditionalProperties;
30
55
  function schemaToGeminiParameters(schema) {
31
56
  // Gemini doesn't accept either the $schema or additionalProperties
32
57
  // attributes, so we need to explicitly remove them.
58
+ // Zod sometimes also makes an array of type (because of .nullish()),
59
+ // which needs cleaning up.
33
60
  const jsonSchema = removeAdditionalProperties((0, types_1.isZodSchema)(schema) ? (0, zod_to_json_schema_1.zodToJsonSchema)(schema) : schema);
34
61
  const { $schema, ...rest } = jsonSchema;
35
62
  return rest;
@@ -9,6 +9,31 @@ obj) {
9
9
  if ("additionalProperties" in newObj) {
10
10
  delete newObj.additionalProperties;
11
11
  }
12
+ if (Array.isArray(obj.type)) {
13
+ const len = obj.type.length;
14
+ const nullIndex = obj.type.indexOf("null");
15
+ if (len === 2 && nullIndex >= 0) {
16
+ // There are only two values set for the type, and one of them is "null".
17
+ // Set the type to the other one and set nullable to true.
18
+ const typeIndex = nullIndex === 0 ? 1 : 0;
19
+ newObj.type = obj.type[typeIndex];
20
+ newObj.nullable = true;
21
+ }
22
+ else if (len === 1 && nullIndex === 0) {
23
+ // This is nullable only without a type, which doesn't
24
+ // make sense for Gemini
25
+ throw new Error("zod_to_gemini_parameters: Gemini cannot handle null type");
26
+ }
27
+ else if (len === 1) {
28
+ // Although an array, it has only one value.
29
+ // So set it to the string to match what Gemini expects.
30
+ newObj.type = obj?.type[0];
31
+ }
32
+ else {
33
+ // Anything else could be a union type, so reject it.
34
+ throw new Error("zod_to_gemini_parameters: Gemini cannot handle union types");
35
+ }
36
+ }
12
37
  for (const key in newObj) {
13
38
  if (key in newObj) {
14
39
  if (Array.isArray(newObj[key])) {
@@ -26,6 +51,8 @@ obj) {
26
51
  export function schemaToGeminiParameters(schema) {
27
52
  // Gemini doesn't accept either the $schema or additionalProperties
28
53
  // attributes, so we need to explicitly remove them.
54
+ // Zod sometimes also makes an array of type (because of .nullish()),
55
+ // which needs cleaning up.
29
56
  const jsonSchema = removeAdditionalProperties(isZodSchema(schema) ? zodToJsonSchema(schema) : schema);
30
57
  const { $schema, ...rest } = jsonSchema;
31
58
  return rest;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/google-common",
3
- "version": "0.2.7",
3
+ "version": "0.2.9",
4
4
  "description": "Core types and classes for Google services.",
5
5
  "type": "module",
6
6
  "engines": {