@langchain/google 0.1.0 → 0.1.1
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/CHANGELOG.md +28 -0
- package/dist/chat_models/base.cjs +31 -40
- package/dist/chat_models/base.cjs.map +1 -1
- package/dist/chat_models/base.js +9 -17
- package/dist/chat_models/base.js.map +1 -1
- package/dist/chat_models/index.cjs +2 -3
- package/dist/chat_models/index.cjs.map +1 -1
- package/dist/chat_models/index.d.cts +0 -1
- package/dist/chat_models/index.d.ts +0 -1
- package/dist/chat_models/index.js.map +1 -1
- package/dist/chat_models/node.cjs +3 -6
- package/dist/chat_models/node.cjs.map +1 -1
- package/dist/chat_models/node.js +1 -3
- package/dist/chat_models/node.js.map +1 -1
- package/dist/chat_models/profiles.cjs +94 -95
- package/dist/chat_models/profiles.cjs.map +1 -1
- package/dist/chat_models/profiles.js +94 -95
- package/dist/chat_models/profiles.js.map +1 -1
- package/dist/chat_models/types.d.cts +4 -3
- package/dist/chat_models/types.d.ts +4 -3
- package/dist/clients/index.cjs +3 -5
- package/dist/clients/index.cjs.map +1 -1
- package/dist/clients/index.js +0 -1
- package/dist/clients/index.js.map +1 -1
- package/dist/clients/node.cjs +8 -15
- package/dist/clients/node.cjs.map +1 -1
- package/dist/clients/node.d.cts +0 -1
- package/dist/clients/node.d.ts +0 -1
- package/dist/clients/node.js +4 -10
- package/dist/clients/node.js.map +1 -1
- package/dist/const.cjs.map +1 -1
- package/dist/const.js.map +1 -1
- package/dist/converters/messages.cjs +46 -67
- package/dist/converters/messages.cjs.map +1 -1
- package/dist/converters/messages.js +22 -42
- package/dist/converters/messages.js.map +1 -1
- package/dist/converters/params.cjs +20 -27
- package/dist/converters/params.cjs.map +1 -1
- package/dist/converters/params.js +20 -27
- package/dist/converters/params.js.map +1 -1
- package/dist/converters/tools.cjs +13 -19
- package/dist/converters/tools.cjs.map +1 -1
- package/dist/converters/tools.js +7 -12
- package/dist/converters/tools.js.map +1 -1
- package/dist/index.cjs +1 -0
- package/dist/node.cjs +1 -0
- package/dist/utils/errors.cjs +34 -30
- package/dist/utils/errors.cjs.map +1 -1
- package/dist/utils/errors.js +34 -30
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/gcp-auth.cjs +10 -6
- package/dist/utils/gcp-auth.cjs.map +1 -1
- package/dist/utils/gcp-auth.js +9 -4
- package/dist/utils/gcp-auth.js.map +1 -1
- package/dist/utils/handler.cjs +3 -4
- package/dist/utils/handler.cjs.map +1 -1
- package/dist/utils/handler.js +1 -1
- package/dist/utils/handler.js.map +1 -1
- package/dist/utils/misc.cjs.map +1 -1
- package/dist/utils/misc.d.cts +6 -2
- package/dist/utils/misc.d.ts +6 -2
- package/dist/utils/misc.js.map +1 -1
- package/dist/utils/stream.cjs.map +1 -1
- package/dist/utils/stream.js.map +1 -1
- package/package.json +4 -4
- package/dist/_virtual/rolldown_runtime.cjs +0 -25
package/dist/clients/node.cjs
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
|
|
2
1
|
const require_const = require('../const.cjs');
|
|
3
2
|
const require_misc = require('../utils/misc.cjs');
|
|
4
3
|
const require_errors = require('../utils/errors.cjs');
|
|
5
4
|
const require_gcp_auth = require('../utils/gcp-auth.cjs');
|
|
6
5
|
const require_index = require('./index.cjs');
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
let _langchain_core_utils_env = require("@langchain/core/utils/env");
|
|
7
|
+
let google_auth_library = require("google-auth-library");
|
|
9
8
|
|
|
10
9
|
//#region src/clients/node.ts
|
|
11
10
|
/**
|
|
@@ -175,17 +174,15 @@ var NodeApiClient = class extends require_index.ApiClient {
|
|
|
175
174
|
constructor(params = {}) {
|
|
176
175
|
super();
|
|
177
176
|
this.params = params;
|
|
178
|
-
this.apiKey = params.apiKey ?? (0,
|
|
177
|
+
this.apiKey = params.apiKey ?? (0, _langchain_core_utils_env.getEnvironmentVariable)("GOOGLE_API_KEY");
|
|
179
178
|
this.credentials = require_misc.iife(() => {
|
|
180
179
|
if (params.credentials) return require_gcp_auth.normalizeGCPCredentials(params.credentials);
|
|
181
|
-
const credentialsVar = (0,
|
|
180
|
+
const credentialsVar = (0, _langchain_core_utils_env.getEnvironmentVariable)("GOOGLE_CLOUD_CREDENTIALS");
|
|
182
181
|
if (credentialsVar) return require_gcp_auth.normalizeGCPCredentials(credentialsVar);
|
|
183
|
-
return void 0;
|
|
184
182
|
});
|
|
185
183
|
this.googleAuth = require_misc.iife(() => {
|
|
186
184
|
if (params.googleAuthOptions) return new google_auth_library.GoogleAuth(params.googleAuthOptions);
|
|
187
185
|
if (!this.apiKey && !this.credentials) return new google_auth_library.GoogleAuth();
|
|
188
|
-
return void 0;
|
|
189
186
|
});
|
|
190
187
|
}
|
|
191
188
|
/**
|
|
@@ -230,12 +227,9 @@ var NodeApiClient = class extends require_index.ApiClient {
|
|
|
230
227
|
async fetch(request) {
|
|
231
228
|
if (this.apiKey) request.headers.set(require_const.GOOGLE_API_KEY_HEADER, this.apiKey);
|
|
232
229
|
else if (this.credentials) request.headers.set(require_const.GCP_API_KEY_HEADER, `Bearer ${require_gcp_auth.getGCPCredentialsAccessToken(this.credentials)}`);
|
|
233
|
-
else if (this.googleAuth) {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
if (value !== null) request.headers.set(key, value);
|
|
237
|
-
});
|
|
238
|
-
}
|
|
230
|
+
else if (this.googleAuth) (await this.googleAuth.getRequestHeaders(request.url)).forEach((value, key) => {
|
|
231
|
+
if (value !== null) request.headers.set(key, value);
|
|
232
|
+
});
|
|
239
233
|
return fetch(request);
|
|
240
234
|
}
|
|
241
235
|
};
|
|
@@ -315,8 +309,7 @@ function ensureAuthScopes(authOptions, requiredScopes) {
|
|
|
315
309
|
};
|
|
316
310
|
else {
|
|
317
311
|
const existingScopes = Array.isArray(authOptions.scopes) ? authOptions.scopes : [authOptions.scopes];
|
|
318
|
-
|
|
319
|
-
if (missingScopes.length > 0) throw new require_errors.ConfigurationError(`Invalid auth scopes. Scopes must include ${requiredScopes.join(", ")}`);
|
|
312
|
+
if (requiredScopes.filter((scope) => !existingScopes.includes(scope)).length > 0) throw new require_errors.ConfigurationError(`Invalid auth scopes. Scopes must include ${requiredScopes.join(", ")}`);
|
|
320
313
|
}
|
|
321
314
|
return authOptions;
|
|
322
315
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.cjs","names":["ApiClient","params: NodeApiClientParams","iife","normalizeGCPCredentials","GoogleAuth","request: Request","GOOGLE_API_KEY_HEADER","GCP_API_KEY_HEADER","getGCPCredentialsAccessToken","authOptions: GoogleAuthOptions","requiredScopes: string[]","ConfigurationError"],"sources":["../../src/clients/node.ts"],"sourcesContent":["import { GoogleAuth, type GoogleAuthOptions } from \"google-auth-library\";\nimport { getEnvironmentVariable } from \"@langchain/core/utils/env\";\nimport { GCP_API_KEY_HEADER, GOOGLE_API_KEY_HEADER } from \"../const.js\";\nimport { ApiClient } from \"./index.js\";\nimport {\n GCPCredentials,\n getGCPCredentialsAccessToken,\n normalizeGCPCredentials,\n} from \"../utils/gcp-auth.js\";\nimport { ConfigurationError } from \"../utils/errors.js\";\nimport { iife } from \"../utils/misc.js\";\n\n/**\n * Configuration parameters for the NodeApiClient.\n *\n * This interface defines the authentication options available for Node.js-based\n * API clients. Authentication can be provided via an API key, GCP service\n * account credentials, or advanced Google Auth options. The client will\n * automatically check environment variables if explicit values are not provided.\n *\n * @interface\n */\nexport interface NodeApiClientParams {\n /**\n * Google API key for authentication.\n *\n * If not provided, the client will attempt to read from the\n * `GOOGLE_API_KEY` environment variable.\n *\n * @see https://cloud.google.com/docs/authentication/api-keys\n */\n apiKey?: string;\n\n /**\n * GCP service account credentials for authentication.\n *\n * Can be provided as either:\n * - A JSON string containing the service account key\n * - A GCPCredentials object\n *\n * If not provided, the client will attempt to read from the\n * `GOOGLE_CLOUD_CREDENTIALS` environment variable.\n *\n * @see https://cloud.google.com/iam/docs/creating-managing-service-account-keys\n */\n credentials?: string | GCPCredentials;\n\n /**\n * Google Auth options configuration.\n *\n * Provides fine-grained control over authentication behavior using the\n * google-auth-library. This option enables:\n * - Custom OAuth2 scopes\n * - Application Default Credentials (ADC)\n * - Impersonation and delegation\n * - Custom credential sources\n *\n * When provided, this takes precedence over simple credential-based auth\n * but is lower priority than API key authentication.\n *\n * @see https://github.com/googleapis/google-auth-library-nodejs\n * @see https://cloud.google.com/docs/authentication/application-default-credentials\n */\n googleAuthOptions?: GoogleAuthOptions;\n}\n\n/**\n * Node.js-specific API client for Google services.\n *\n * This client provides comprehensive authentication for Google API requests in\n * Node.js environments, leveraging the full capabilities of the google-auth-library.\n * It supports three authentication methods with the following priority:\n *\n * 1. **API Key Authentication**: Simple key-based authentication suitable for\n * public APIs and development environments.\n *\n * 2. **Service Account Credentials**: OAuth2-based authentication using GCP\n * service account keys. The client automatically handles token generation\n * and caching using a web-compatible implementation.\n *\n * 3. **Google Auth Library**: Advanced authentication using google-auth-library,\n * supporting Application Default Credentials (ADC), custom scopes, and\n * various credential sources.\n *\n * The client follows this authentication priority:\n * 1. Explicit `apiKey` parameter\n * 2. `GOOGLE_API_KEY` environment variable\n * 3. Explicit `credentials` parameter\n * 4. `GOOGLE_CLOUD_CREDENTIALS` environment variable\n * 5. `googleAuthOptions` parameter\n * 6. Application Default Credentials (if googleAuthOptions is provided without explicit credentials)\n *\n * @extends ApiClient\n *\n * @example\n * ```typescript\n * // Using API key\n * const client = new NodeApiClient({\n * apiKey: 'your-api-key'\n * });\n *\n * // Using service account credentials\n * const client = new NodeApiClient({\n * credentials: {\n * type: \"service_account\",\n * project_id: \"my-project\",\n * private_key_id: \"key-id\",\n * private_key: \"-----BEGIN PRIVATE KEY-----\\n...\",\n * client_email: \"service-account@project.iam.gserviceaccount.com\",\n * // ... other required fields\n * }\n * });\n *\n * // Using Google Auth with custom scopes\n * const client = new NodeApiClient({\n * googleAuthOptions: {\n * scopes: ['https://www.googleapis.com/auth/cloud-platform'],\n * keyFilename: '/path/to/service-account-key.json'\n * }\n * });\n *\n * // Using Application Default Credentials\n * const client = new NodeApiClient({\n * googleAuthOptions: {}\n * });\n *\n * // Using environment variables\n * // Set GOOGLE_API_KEY or GOOGLE_CLOUD_CREDENTIALS\n * const client = new NodeApiClient();\n *\n * // Make authenticated requests\n * const request = new Request('https://api.google.com/...');\n * const response = await client.fetch(request);\n * ```\n *\n * @remarks\n * - API keys are added via the `X-Goog-Api-Key` header\n * - Service account tokens are added via the `Authorization` header with Bearer scheme\n * - Google Auth headers are automatically generated and added by google-auth-library\n * - Tokens are automatically cached and refreshed as needed\n * - For web/edge environments without google-auth-library, use WebApiClient instead\n *\n * @see {@link WebApiClient} for web-compatible authentication without google-auth-library\n * @see {@link GCPCredentials} for service account credential structure\n * @see {@link GoogleAuthOptions} for advanced authentication configuration\n */\nexport class NodeApiClient extends ApiClient {\n hasApiKey(): boolean {\n return typeof this.apiKey === \"string\" && this.apiKey !== \"\";\n }\n\n async getProjectId(): Promise<string> {\n if (typeof this.credentials !== \"undefined\") {\n return this.credentials.project_id;\n } else if (typeof this.googleAuth !== \"undefined\") {\n return this.googleAuth.getProjectId();\n } else {\n return super.getProjectId();\n }\n }\n\n /**\n * The Google API key used for authentication, if provided.\n *\n * This value is resolved from either the constructor parameter or the\n * `GOOGLE_API_KEY` environment variable.\n *\n * @protected\n */\n protected apiKey?: string;\n\n /**\n * The normalized GCP service account credentials, if provided.\n *\n * This value is resolved from either the constructor parameter or the\n * `GOOGLE_CLOUD_CREDENTIALS` environment variable, and is normalized\n * to ensure immutability.\n *\n * @protected\n */\n protected credentials?: GCPCredentials;\n\n /**\n * The Google Auth instance for advanced authentication, if configured.\n *\n * This instance is created when `googleAuthOptions` is provided and\n * handles Application Default Credentials, custom scopes, and other\n * advanced authentication scenarios.\n *\n * @protected\n */\n protected googleAuth?: GoogleAuth;\n\n /**\n * Creates a new NodeApiClient instance.\n *\n * The constructor initializes authentication credentials by checking:\n * 1. Explicit parameters passed to the constructor\n * 2. Environment variables (`GOOGLE_API_KEY`, `GOOGLE_CLOUD_CREDENTIALS`)\n * 3. Application Default Credentials (if googleAuthOptions is provided)\n *\n * Credentials are normalized and frozen to prevent accidental modification.\n * The GoogleAuth instance is lazily initialized only when googleAuthOptions\n * is provided.\n *\n * @param params - Configuration parameters for the client. Defaults to an empty object.\n *\n * @example\n * ```typescript\n * // Minimal configuration (uses environment variables or ADC)\n * const client = new NodeApiClient();\n *\n * // With explicit API key\n * const client = new WebApiClient({\n * apiKey: 'your-api-key'\n * });\n *\n * // With service account credentials as JSON string\n * const client = new WebApiClient({\n * credentials: '{\"type\":\"service_account\",...}'\n * });\n *\n * // With service account credentials as object\n * const client = new NodeApiClient({\n * credentials: {\n * type: \"service_account\",\n * // ... other fields\n * }\n * });\n *\n * // With Google Auth options\n * const client = new NodeApiClient({\n * googleAuthOptions: {\n * scopes: ['https://www.googleapis.com/auth/cloud-platform'],\n * projectId: 'my-project'\n * }\n * });\n * ```\n */\n constructor(protected params: NodeApiClientParams = {}) {\n super();\n\n this.apiKey = params.apiKey ?? getEnvironmentVariable(\"GOOGLE_API_KEY\");\n this.credentials = iife(() => {\n if (params.credentials) {\n return normalizeGCPCredentials(params.credentials);\n }\n const credentialsVar = getEnvironmentVariable(\"GOOGLE_CLOUD_CREDENTIALS\");\n if (credentialsVar) {\n return normalizeGCPCredentials(credentialsVar);\n }\n return undefined;\n });\n this.googleAuth = iife(() => {\n if (params.googleAuthOptions) {\n return new GoogleAuth(params.googleAuthOptions);\n }\n if (!this.apiKey && !this.credentials) {\n return new GoogleAuth();\n }\n return undefined;\n });\n }\n\n /**\n * Executes an HTTP request with appropriate Google API authentication.\n *\n * This method adds authentication headers to the request based on the\n * configured authentication method, following this priority:\n *\n * 1. If an API key is configured, adds the `X-Goog-Api-Key` header\n * 2. If service account credentials are configured, generates an access token\n * and adds it via the `Authorization` header with Bearer scheme\n * 3. If Google Auth is configured, uses google-auth-library to generate\n * appropriate authentication headers (may include Authorization, x-goog-user-project, etc.)\n *\n * The authentication priority ensures that explicit API keys take precedence,\n * followed by service account credentials, and finally Google Auth options.\n *\n * @param request - The HTTP request to execute. Headers will be modified\n * in-place to include authentication information.\n * @returns A Promise that resolves to the HTTP response\n *\n * @throws {AuthError} If service account authentication fails (e.g., invalid\n * credentials, network error, or token generation failure)\n * @throws {Error} If Google Auth authentication fails (e.g., missing credentials,\n * invalid configuration, or ADC not available)\n *\n * @example\n * ```typescript\n * const client = new NodeApiClient({ apiKey: 'your-key' });\n * const request = new Request('https://generativelanguage.googleapis.com/v1/models');\n * const response = await client.fetch(request);\n * const data = await response.json();\n * ```\n *\n * @remarks\n * - The request object is modified in-place by adding headers\n * - Service account tokens are automatically cached and refreshed\n * - Google Auth tokens are managed by google-auth-library with automatic refresh\n * - Only one authentication method is used per request (based on priority)\n * - Google Auth may add multiple headers depending on the authentication type\n */\n async fetch(request: Request): Promise<Response> {\n if (this.apiKey) {\n request.headers.set(GOOGLE_API_KEY_HEADER, this.apiKey);\n } else if (this.credentials) {\n request.headers.set(\n GCP_API_KEY_HEADER,\n `Bearer ${getGCPCredentialsAccessToken(this.credentials)}`\n );\n } else if (this.googleAuth) {\n const authHeaders = await this.googleAuth.getRequestHeaders(request.url);\n authHeaders.forEach((value, key) => {\n if (value !== null) {\n request.headers.set(key, value);\n }\n });\n }\n return fetch(request);\n }\n}\n\n/**\n * Ensures that Google Auth options include required OAuth2 scopes.\n *\n * This utility function validates and augments GoogleAuthOptions to ensure\n * that all required OAuth2 scopes are present. It handles three scenarios:\n *\n * 1. **No auth options provided**: Creates new options with required scopes\n * 2. **Auth options without scopes**: Adds required scopes to existing options\n * 3. **Auth options with scopes**: Validates that all required scopes are present\n *\n * This is particularly useful when working with Google APIs that require specific\n * scopes for access, ensuring that authentication is properly configured before\n * making API requests.\n *\n * @param authOptions - The existing Google Auth options to validate/augment.\n * Can be undefined or an empty object.\n * @param requiredScopes - Array of OAuth2 scope URLs that must be present.\n * These are typically Google API scope URLs like\n * 'https://www.googleapis.com/auth/cloud-platform'\n * @returns The validated/augmented GoogleAuthOptions with all required scopes\n *\n * @throws {Error} If authOptions already has scopes but is missing any of the\n * required scopes. This prevents accidental scope reduction that\n * could break API access.\n *\n * @example\n * ```typescript\n * // Create new options with required scopes\n * const options = ensureAuthScopes(undefined, [\n * 'https://www.googleapis.com/auth/cloud-platform'\n * ]);\n * // Result: { scopes: ['https://www.googleapis.com/auth/cloud-platform'] }\n *\n * // Add scopes to existing options\n * const options = ensureAuthScopes(\n * { projectId: 'my-project' },\n * ['https://www.googleapis.com/auth/cloud-platform']\n * );\n * // Result: { projectId: 'my-project', scopes: [...] }\n *\n * // Validate existing scopes\n * const options = ensureAuthScopes(\n * { scopes: ['https://www.googleapis.com/auth/cloud-platform'] },\n * ['https://www.googleapis.com/auth/cloud-platform']\n * );\n * // Result: Original options (validation passed)\n *\n * // Error case - missing required scope\n * try {\n * ensureAuthScopes(\n * { scopes: ['https://www.googleapis.com/auth/userinfo.email'] },\n * ['https://www.googleapis.com/auth/cloud-platform']\n * );\n * } catch (error) {\n * // Error: Invalid auth scopes. Scopes must include ...\n * }\n * ```\n *\n * @remarks\n * - Scopes can be provided as a string or array of strings in GoogleAuthOptions\n * - The function normalizes single-string scopes to arrays for validation\n * - Required scopes are not automatically added if existing scopes are present;\n * instead, an error is thrown to prevent unintended scope changes\n * - This function does not modify the original authOptions object\n *\n * @see https://developers.google.com/identity/protocols/oauth2/scopes\n * @see {@link GoogleAuthOptions} for the full authentication configuration interface\n */\nexport function ensureAuthScopes(\n authOptions: GoogleAuthOptions,\n requiredScopes: string[]\n): GoogleAuthOptions {\n if (!authOptions) {\n return { scopes: requiredScopes };\n } else if (!authOptions.scopes) {\n return { ...authOptions, scopes: requiredScopes };\n } else {\n const existingScopes = Array.isArray(authOptions.scopes)\n ? authOptions.scopes\n : [authOptions.scopes];\n const missingScopes = requiredScopes.filter(\n (scope) => !existingScopes.includes(scope)\n );\n if (missingScopes.length > 0) {\n throw new ConfigurationError(\n `Invalid auth scopes. Scopes must include ${requiredScopes.join(\", \")}`\n );\n }\n }\n return authOptions;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkJA,IAAa,gBAAb,cAAmCA,wBAAU;CAC3C,YAAqB;AACnB,SAAO,OAAO,KAAK,WAAW,YAAY,KAAK,WAAW;CAC3D;CAED,MAAM,eAAgC;AACpC,MAAI,OAAO,KAAK,gBAAgB,YAC9B,QAAO,KAAK,YAAY;WACf,OAAO,KAAK,eAAe,YACpC,QAAO,KAAK,WAAW,cAAc;MAErC,QAAO,MAAM,cAAc;CAE9B;;;;;;;;;CAUD,AAAU;;;;;;;;;;CAWV,AAAU;;;;;;;;;;CAWV,AAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgDV,YAAsBC,SAA8B,CAAE,GAAE;EACtD,OAAO;EADa;EAGpB,KAAK,SAAS,OAAO,iEAAiC,iBAAiB;EACvE,KAAK,cAAcC,kBAAK,MAAM;AAC5B,OAAI,OAAO,YACT,QAAOC,yCAAwB,OAAO,YAAY;GAEpD,MAAM,wEAAwC,2BAA2B;AACzE,OAAI,eACF,QAAOA,yCAAwB,eAAe;AAEhD,UAAO;EACR,EAAC;EACF,KAAK,aAAaD,kBAAK,MAAM;AAC3B,OAAI,OAAO,kBACT,QAAO,IAAIE,+BAAW,OAAO;AAE/B,OAAI,CAAC,KAAK,UAAU,CAAC,KAAK,YACxB,QAAO,IAAIA;AAEb,UAAO;EACR,EAAC;CACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyCD,MAAM,MAAMC,SAAqC;AAC/C,MAAI,KAAK,QACP,QAAQ,QAAQ,IAAIC,qCAAuB,KAAK,OAAO;WAC9C,KAAK,aACd,QAAQ,QAAQ,IACdC,kCACA,CAAC,OAAO,EAAEC,8CAA6B,KAAK,YAAY,EAAE,CAC3D;WACQ,KAAK,YAAY;GAC1B,MAAM,cAAc,MAAM,KAAK,WAAW,kBAAkB,QAAQ,IAAI;GACxE,YAAY,QAAQ,CAAC,OAAO,QAAQ;AAClC,QAAI,UAAU,MACZ,QAAQ,QAAQ,IAAI,KAAK,MAAM;GAElC,EAAC;EACH;AACD,SAAO,MAAM,QAAQ;CACtB;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsED,SAAgB,iBACdC,aACAC,gBACmB;AACnB,KAAI,CAAC,YACH,QAAO,EAAE,QAAQ,eAAgB;UACxB,CAAC,YAAY,OACtB,QAAO;EAAE,GAAG;EAAa,QAAQ;CAAgB;MAC5C;EACL,MAAM,iBAAiB,MAAM,QAAQ,YAAY,OAAO,GACpD,YAAY,SACZ,CAAC,YAAY,MAAO;EACxB,MAAM,gBAAgB,eAAe,OACnC,CAAC,UAAU,CAAC,eAAe,SAAS,MAAM,CAC3C;AACD,MAAI,cAAc,SAAS,EACzB,OAAM,IAAIC,kCACR,CAAC,yCAAyC,EAAE,eAAe,KAAK,KAAK,EAAE;CAG5E;AACD,QAAO;AACR"}
|
|
1
|
+
{"version":3,"file":"node.cjs","names":["ApiClient","iife","normalizeGCPCredentials","GoogleAuth","GOOGLE_API_KEY_HEADER","GCP_API_KEY_HEADER","getGCPCredentialsAccessToken","ConfigurationError"],"sources":["../../src/clients/node.ts"],"sourcesContent":["import { GoogleAuth, type GoogleAuthOptions } from \"google-auth-library\";\nimport { getEnvironmentVariable } from \"@langchain/core/utils/env\";\nimport { GCP_API_KEY_HEADER, GOOGLE_API_KEY_HEADER } from \"../const.js\";\nimport { ApiClient } from \"./index.js\";\nimport {\n GCPCredentials,\n getGCPCredentialsAccessToken,\n normalizeGCPCredentials,\n} from \"../utils/gcp-auth.js\";\nimport { ConfigurationError } from \"../utils/errors.js\";\nimport { iife } from \"../utils/misc.js\";\n\n/**\n * Configuration parameters for the NodeApiClient.\n *\n * This interface defines the authentication options available for Node.js-based\n * API clients. Authentication can be provided via an API key, GCP service\n * account credentials, or advanced Google Auth options. The client will\n * automatically check environment variables if explicit values are not provided.\n *\n * @interface\n */\nexport interface NodeApiClientParams {\n /**\n * Google API key for authentication.\n *\n * If not provided, the client will attempt to read from the\n * `GOOGLE_API_KEY` environment variable.\n *\n * @see https://cloud.google.com/docs/authentication/api-keys\n */\n apiKey?: string;\n\n /**\n * GCP service account credentials for authentication.\n *\n * Can be provided as either:\n * - A JSON string containing the service account key\n * - A GCPCredentials object\n *\n * If not provided, the client will attempt to read from the\n * `GOOGLE_CLOUD_CREDENTIALS` environment variable.\n *\n * @see https://cloud.google.com/iam/docs/creating-managing-service-account-keys\n */\n credentials?: string | GCPCredentials;\n\n /**\n * Google Auth options configuration.\n *\n * Provides fine-grained control over authentication behavior using the\n * google-auth-library. This option enables:\n * - Custom OAuth2 scopes\n * - Application Default Credentials (ADC)\n * - Impersonation and delegation\n * - Custom credential sources\n *\n * When provided, this takes precedence over simple credential-based auth\n * but is lower priority than API key authentication.\n *\n * @see https://github.com/googleapis/google-auth-library-nodejs\n * @see https://cloud.google.com/docs/authentication/application-default-credentials\n */\n googleAuthOptions?: GoogleAuthOptions;\n}\n\n/**\n * Node.js-specific API client for Google services.\n *\n * This client provides comprehensive authentication for Google API requests in\n * Node.js environments, leveraging the full capabilities of the google-auth-library.\n * It supports three authentication methods with the following priority:\n *\n * 1. **API Key Authentication**: Simple key-based authentication suitable for\n * public APIs and development environments.\n *\n * 2. **Service Account Credentials**: OAuth2-based authentication using GCP\n * service account keys. The client automatically handles token generation\n * and caching using a web-compatible implementation.\n *\n * 3. **Google Auth Library**: Advanced authentication using google-auth-library,\n * supporting Application Default Credentials (ADC), custom scopes, and\n * various credential sources.\n *\n * The client follows this authentication priority:\n * 1. Explicit `apiKey` parameter\n * 2. `GOOGLE_API_KEY` environment variable\n * 3. Explicit `credentials` parameter\n * 4. `GOOGLE_CLOUD_CREDENTIALS` environment variable\n * 5. `googleAuthOptions` parameter\n * 6. Application Default Credentials (if googleAuthOptions is provided without explicit credentials)\n *\n * @extends ApiClient\n *\n * @example\n * ```typescript\n * // Using API key\n * const client = new NodeApiClient({\n * apiKey: 'your-api-key'\n * });\n *\n * // Using service account credentials\n * const client = new NodeApiClient({\n * credentials: {\n * type: \"service_account\",\n * project_id: \"my-project\",\n * private_key_id: \"key-id\",\n * private_key: \"-----BEGIN PRIVATE KEY-----\\n...\",\n * client_email: \"service-account@project.iam.gserviceaccount.com\",\n * // ... other required fields\n * }\n * });\n *\n * // Using Google Auth with custom scopes\n * const client = new NodeApiClient({\n * googleAuthOptions: {\n * scopes: ['https://www.googleapis.com/auth/cloud-platform'],\n * keyFilename: '/path/to/service-account-key.json'\n * }\n * });\n *\n * // Using Application Default Credentials\n * const client = new NodeApiClient({\n * googleAuthOptions: {}\n * });\n *\n * // Using environment variables\n * // Set GOOGLE_API_KEY or GOOGLE_CLOUD_CREDENTIALS\n * const client = new NodeApiClient();\n *\n * // Make authenticated requests\n * const request = new Request('https://api.google.com/...');\n * const response = await client.fetch(request);\n * ```\n *\n * @remarks\n * - API keys are added via the `X-Goog-Api-Key` header\n * - Service account tokens are added via the `Authorization` header with Bearer scheme\n * - Google Auth headers are automatically generated and added by google-auth-library\n * - Tokens are automatically cached and refreshed as needed\n * - For web/edge environments without google-auth-library, use WebApiClient instead\n *\n * @see {@link WebApiClient} for web-compatible authentication without google-auth-library\n * @see {@link GCPCredentials} for service account credential structure\n * @see {@link GoogleAuthOptions} for advanced authentication configuration\n */\nexport class NodeApiClient extends ApiClient {\n hasApiKey(): boolean {\n return typeof this.apiKey === \"string\" && this.apiKey !== \"\";\n }\n\n async getProjectId(): Promise<string> {\n if (typeof this.credentials !== \"undefined\") {\n return this.credentials.project_id;\n } else if (typeof this.googleAuth !== \"undefined\") {\n return this.googleAuth.getProjectId();\n } else {\n return super.getProjectId();\n }\n }\n\n /**\n * The Google API key used for authentication, if provided.\n *\n * This value is resolved from either the constructor parameter or the\n * `GOOGLE_API_KEY` environment variable.\n *\n * @protected\n */\n protected apiKey?: string;\n\n /**\n * The normalized GCP service account credentials, if provided.\n *\n * This value is resolved from either the constructor parameter or the\n * `GOOGLE_CLOUD_CREDENTIALS` environment variable, and is normalized\n * to ensure immutability.\n *\n * @protected\n */\n protected credentials?: GCPCredentials;\n\n /**\n * The Google Auth instance for advanced authentication, if configured.\n *\n * This instance is created when `googleAuthOptions` is provided and\n * handles Application Default Credentials, custom scopes, and other\n * advanced authentication scenarios.\n *\n * @protected\n */\n protected googleAuth?: GoogleAuth;\n\n /**\n * Creates a new NodeApiClient instance.\n *\n * The constructor initializes authentication credentials by checking:\n * 1. Explicit parameters passed to the constructor\n * 2. Environment variables (`GOOGLE_API_KEY`, `GOOGLE_CLOUD_CREDENTIALS`)\n * 3. Application Default Credentials (if googleAuthOptions is provided)\n *\n * Credentials are normalized and frozen to prevent accidental modification.\n * The GoogleAuth instance is lazily initialized only when googleAuthOptions\n * is provided.\n *\n * @param params - Configuration parameters for the client. Defaults to an empty object.\n *\n * @example\n * ```typescript\n * // Minimal configuration (uses environment variables or ADC)\n * const client = new NodeApiClient();\n *\n * // With explicit API key\n * const client = new WebApiClient({\n * apiKey: 'your-api-key'\n * });\n *\n * // With service account credentials as JSON string\n * const client = new WebApiClient({\n * credentials: '{\"type\":\"service_account\",...}'\n * });\n *\n * // With service account credentials as object\n * const client = new NodeApiClient({\n * credentials: {\n * type: \"service_account\",\n * // ... other fields\n * }\n * });\n *\n * // With Google Auth options\n * const client = new NodeApiClient({\n * googleAuthOptions: {\n * scopes: ['https://www.googleapis.com/auth/cloud-platform'],\n * projectId: 'my-project'\n * }\n * });\n * ```\n */\n constructor(protected params: NodeApiClientParams = {}) {\n super();\n\n this.apiKey = params.apiKey ?? getEnvironmentVariable(\"GOOGLE_API_KEY\");\n this.credentials = iife(() => {\n if (params.credentials) {\n return normalizeGCPCredentials(params.credentials);\n }\n const credentialsVar = getEnvironmentVariable(\"GOOGLE_CLOUD_CREDENTIALS\");\n if (credentialsVar) {\n return normalizeGCPCredentials(credentialsVar);\n }\n return undefined;\n });\n this.googleAuth = iife(() => {\n if (params.googleAuthOptions) {\n return new GoogleAuth(params.googleAuthOptions);\n }\n if (!this.apiKey && !this.credentials) {\n return new GoogleAuth();\n }\n return undefined;\n });\n }\n\n /**\n * Executes an HTTP request with appropriate Google API authentication.\n *\n * This method adds authentication headers to the request based on the\n * configured authentication method, following this priority:\n *\n * 1. If an API key is configured, adds the `X-Goog-Api-Key` header\n * 2. If service account credentials are configured, generates an access token\n * and adds it via the `Authorization` header with Bearer scheme\n * 3. If Google Auth is configured, uses google-auth-library to generate\n * appropriate authentication headers (may include Authorization, x-goog-user-project, etc.)\n *\n * The authentication priority ensures that explicit API keys take precedence,\n * followed by service account credentials, and finally Google Auth options.\n *\n * @param request - The HTTP request to execute. Headers will be modified\n * in-place to include authentication information.\n * @returns A Promise that resolves to the HTTP response\n *\n * @throws {AuthError} If service account authentication fails (e.g., invalid\n * credentials, network error, or token generation failure)\n * @throws {Error} If Google Auth authentication fails (e.g., missing credentials,\n * invalid configuration, or ADC not available)\n *\n * @example\n * ```typescript\n * const client = new NodeApiClient({ apiKey: 'your-key' });\n * const request = new Request('https://generativelanguage.googleapis.com/v1/models');\n * const response = await client.fetch(request);\n * const data = await response.json();\n * ```\n *\n * @remarks\n * - The request object is modified in-place by adding headers\n * - Service account tokens are automatically cached and refreshed\n * - Google Auth tokens are managed by google-auth-library with automatic refresh\n * - Only one authentication method is used per request (based on priority)\n * - Google Auth may add multiple headers depending on the authentication type\n */\n async fetch(request: Request): Promise<Response> {\n if (this.apiKey) {\n request.headers.set(GOOGLE_API_KEY_HEADER, this.apiKey);\n } else if (this.credentials) {\n request.headers.set(\n GCP_API_KEY_HEADER,\n `Bearer ${getGCPCredentialsAccessToken(this.credentials)}`\n );\n } else if (this.googleAuth) {\n const authHeaders = await this.googleAuth.getRequestHeaders(request.url);\n authHeaders.forEach((value, key) => {\n if (value !== null) {\n request.headers.set(key, value);\n }\n });\n }\n return fetch(request);\n }\n}\n\n/**\n * Ensures that Google Auth options include required OAuth2 scopes.\n *\n * This utility function validates and augments GoogleAuthOptions to ensure\n * that all required OAuth2 scopes are present. It handles three scenarios:\n *\n * 1. **No auth options provided**: Creates new options with required scopes\n * 2. **Auth options without scopes**: Adds required scopes to existing options\n * 3. **Auth options with scopes**: Validates that all required scopes are present\n *\n * This is particularly useful when working with Google APIs that require specific\n * scopes for access, ensuring that authentication is properly configured before\n * making API requests.\n *\n * @param authOptions - The existing Google Auth options to validate/augment.\n * Can be undefined or an empty object.\n * @param requiredScopes - Array of OAuth2 scope URLs that must be present.\n * These are typically Google API scope URLs like\n * 'https://www.googleapis.com/auth/cloud-platform'\n * @returns The validated/augmented GoogleAuthOptions with all required scopes\n *\n * @throws {Error} If authOptions already has scopes but is missing any of the\n * required scopes. This prevents accidental scope reduction that\n * could break API access.\n *\n * @example\n * ```typescript\n * // Create new options with required scopes\n * const options = ensureAuthScopes(undefined, [\n * 'https://www.googleapis.com/auth/cloud-platform'\n * ]);\n * // Result: { scopes: ['https://www.googleapis.com/auth/cloud-platform'] }\n *\n * // Add scopes to existing options\n * const options = ensureAuthScopes(\n * { projectId: 'my-project' },\n * ['https://www.googleapis.com/auth/cloud-platform']\n * );\n * // Result: { projectId: 'my-project', scopes: [...] }\n *\n * // Validate existing scopes\n * const options = ensureAuthScopes(\n * { scopes: ['https://www.googleapis.com/auth/cloud-platform'] },\n * ['https://www.googleapis.com/auth/cloud-platform']\n * );\n * // Result: Original options (validation passed)\n *\n * // Error case - missing required scope\n * try {\n * ensureAuthScopes(\n * { scopes: ['https://www.googleapis.com/auth/userinfo.email'] },\n * ['https://www.googleapis.com/auth/cloud-platform']\n * );\n * } catch (error) {\n * // Error: Invalid auth scopes. Scopes must include ...\n * }\n * ```\n *\n * @remarks\n * - Scopes can be provided as a string or array of strings in GoogleAuthOptions\n * - The function normalizes single-string scopes to arrays for validation\n * - Required scopes are not automatically added if existing scopes are present;\n * instead, an error is thrown to prevent unintended scope changes\n * - This function does not modify the original authOptions object\n *\n * @see https://developers.google.com/identity/protocols/oauth2/scopes\n * @see {@link GoogleAuthOptions} for the full authentication configuration interface\n */\nexport function ensureAuthScopes(\n authOptions: GoogleAuthOptions,\n requiredScopes: string[]\n): GoogleAuthOptions {\n if (!authOptions) {\n return { scopes: requiredScopes };\n } else if (!authOptions.scopes) {\n return { ...authOptions, scopes: requiredScopes };\n } else {\n const existingScopes = Array.isArray(authOptions.scopes)\n ? authOptions.scopes\n : [authOptions.scopes];\n const missingScopes = requiredScopes.filter(\n (scope) => !existingScopes.includes(scope)\n );\n if (missingScopes.length > 0) {\n throw new ConfigurationError(\n `Invalid auth scopes. Scopes must include ${requiredScopes.join(\", \")}`\n );\n }\n }\n return authOptions;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkJA,IAAa,gBAAb,cAAmCA,wBAAU;CAC3C,YAAqB;AACnB,SAAO,OAAO,KAAK,WAAW,YAAY,KAAK,WAAW;;CAG5D,MAAM,eAAgC;AACpC,MAAI,OAAO,KAAK,gBAAgB,YAC9B,QAAO,KAAK,YAAY;WACf,OAAO,KAAK,eAAe,YACpC,QAAO,KAAK,WAAW,cAAc;MAErC,QAAO,MAAM,cAAc;;;;;;;;;;CAY/B,AAAU;;;;;;;;;;CAWV,AAAU;;;;;;;;;;CAWV,AAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgDV,YAAY,AAAU,SAA8B,EAAE,EAAE;AACtD,SAAO;EADa;AAGpB,OAAK,SAAS,OAAO,gEAAiC,iBAAiB;AACvE,OAAK,cAAcC,wBAAW;AAC5B,OAAI,OAAO,YACT,QAAOC,yCAAwB,OAAO,YAAY;GAEpD,MAAM,uEAAwC,2BAA2B;AACzE,OAAI,eACF,QAAOA,yCAAwB,eAAe;IAGhD;AACF,OAAK,aAAaD,wBAAW;AAC3B,OAAI,OAAO,kBACT,QAAO,IAAIE,+BAAW,OAAO,kBAAkB;AAEjD,OAAI,CAAC,KAAK,UAAU,CAAC,KAAK,YACxB,QAAO,IAAIA,gCAAY;IAGzB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0CJ,MAAM,MAAM,SAAqC;AAC/C,MAAI,KAAK,OACP,SAAQ,QAAQ,IAAIC,qCAAuB,KAAK,OAAO;WAC9C,KAAK,YACd,SAAQ,QAAQ,IACdC,kCACA,UAAUC,8CAA6B,KAAK,YAAY,GACzD;WACQ,KAAK,WAEd,EADoB,MAAM,KAAK,WAAW,kBAAkB,QAAQ,IAAI,EAC5D,SAAS,OAAO,QAAQ;AAClC,OAAI,UAAU,KACZ,SAAQ,QAAQ,IAAI,KAAK,MAAM;IAEjC;AAEJ,SAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwEzB,SAAgB,iBACd,aACA,gBACmB;AACnB,KAAI,CAAC,YACH,QAAO,EAAE,QAAQ,gBAAgB;UACxB,CAAC,YAAY,OACtB,QAAO;EAAE,GAAG;EAAa,QAAQ;EAAgB;MAC5C;EACL,MAAM,iBAAiB,MAAM,QAAQ,YAAY,OAAO,GACpD,YAAY,SACZ,CAAC,YAAY,OAAO;AAIxB,MAHsB,eAAe,QAClC,UAAU,CAAC,eAAe,SAAS,MAAM,CAC3C,CACiB,SAAS,EACzB,OAAM,IAAIC,kCACR,4CAA4C,eAAe,KAAK,KAAK,GACtE;;AAGL,QAAO"}
|
package/dist/clients/node.d.cts
CHANGED
package/dist/clients/node.d.ts
CHANGED
package/dist/clients/node.js
CHANGED
|
@@ -179,12 +179,10 @@ var NodeApiClient = class extends ApiClient {
|
|
|
179
179
|
if (params.credentials) return normalizeGCPCredentials(params.credentials);
|
|
180
180
|
const credentialsVar = getEnvironmentVariable("GOOGLE_CLOUD_CREDENTIALS");
|
|
181
181
|
if (credentialsVar) return normalizeGCPCredentials(credentialsVar);
|
|
182
|
-
return void 0;
|
|
183
182
|
});
|
|
184
183
|
this.googleAuth = iife(() => {
|
|
185
184
|
if (params.googleAuthOptions) return new GoogleAuth(params.googleAuthOptions);
|
|
186
185
|
if (!this.apiKey && !this.credentials) return new GoogleAuth();
|
|
187
|
-
return void 0;
|
|
188
186
|
});
|
|
189
187
|
}
|
|
190
188
|
/**
|
|
@@ -229,12 +227,9 @@ var NodeApiClient = class extends ApiClient {
|
|
|
229
227
|
async fetch(request) {
|
|
230
228
|
if (this.apiKey) request.headers.set(GOOGLE_API_KEY_HEADER, this.apiKey);
|
|
231
229
|
else if (this.credentials) request.headers.set(GCP_API_KEY_HEADER, `Bearer ${getGCPCredentialsAccessToken(this.credentials)}`);
|
|
232
|
-
else if (this.googleAuth) {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
if (value !== null) request.headers.set(key, value);
|
|
236
|
-
});
|
|
237
|
-
}
|
|
230
|
+
else if (this.googleAuth) (await this.googleAuth.getRequestHeaders(request.url)).forEach((value, key) => {
|
|
231
|
+
if (value !== null) request.headers.set(key, value);
|
|
232
|
+
});
|
|
238
233
|
return fetch(request);
|
|
239
234
|
}
|
|
240
235
|
};
|
|
@@ -314,8 +309,7 @@ function ensureAuthScopes(authOptions, requiredScopes) {
|
|
|
314
309
|
};
|
|
315
310
|
else {
|
|
316
311
|
const existingScopes = Array.isArray(authOptions.scopes) ? authOptions.scopes : [authOptions.scopes];
|
|
317
|
-
|
|
318
|
-
if (missingScopes.length > 0) throw new ConfigurationError(`Invalid auth scopes. Scopes must include ${requiredScopes.join(", ")}`);
|
|
312
|
+
if (requiredScopes.filter((scope) => !existingScopes.includes(scope)).length > 0) throw new ConfigurationError(`Invalid auth scopes. Scopes must include ${requiredScopes.join(", ")}`);
|
|
319
313
|
}
|
|
320
314
|
return authOptions;
|
|
321
315
|
}
|
package/dist/clients/node.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.js","names":["params: NodeApiClientParams","request: Request","authOptions: GoogleAuthOptions","requiredScopes: string[]"],"sources":["../../src/clients/node.ts"],"sourcesContent":["import { GoogleAuth, type GoogleAuthOptions } from \"google-auth-library\";\nimport { getEnvironmentVariable } from \"@langchain/core/utils/env\";\nimport { GCP_API_KEY_HEADER, GOOGLE_API_KEY_HEADER } from \"../const.js\";\nimport { ApiClient } from \"./index.js\";\nimport {\n GCPCredentials,\n getGCPCredentialsAccessToken,\n normalizeGCPCredentials,\n} from \"../utils/gcp-auth.js\";\nimport { ConfigurationError } from \"../utils/errors.js\";\nimport { iife } from \"../utils/misc.js\";\n\n/**\n * Configuration parameters for the NodeApiClient.\n *\n * This interface defines the authentication options available for Node.js-based\n * API clients. Authentication can be provided via an API key, GCP service\n * account credentials, or advanced Google Auth options. The client will\n * automatically check environment variables if explicit values are not provided.\n *\n * @interface\n */\nexport interface NodeApiClientParams {\n /**\n * Google API key for authentication.\n *\n * If not provided, the client will attempt to read from the\n * `GOOGLE_API_KEY` environment variable.\n *\n * @see https://cloud.google.com/docs/authentication/api-keys\n */\n apiKey?: string;\n\n /**\n * GCP service account credentials for authentication.\n *\n * Can be provided as either:\n * - A JSON string containing the service account key\n * - A GCPCredentials object\n *\n * If not provided, the client will attempt to read from the\n * `GOOGLE_CLOUD_CREDENTIALS` environment variable.\n *\n * @see https://cloud.google.com/iam/docs/creating-managing-service-account-keys\n */\n credentials?: string | GCPCredentials;\n\n /**\n * Google Auth options configuration.\n *\n * Provides fine-grained control over authentication behavior using the\n * google-auth-library. This option enables:\n * - Custom OAuth2 scopes\n * - Application Default Credentials (ADC)\n * - Impersonation and delegation\n * - Custom credential sources\n *\n * When provided, this takes precedence over simple credential-based auth\n * but is lower priority than API key authentication.\n *\n * @see https://github.com/googleapis/google-auth-library-nodejs\n * @see https://cloud.google.com/docs/authentication/application-default-credentials\n */\n googleAuthOptions?: GoogleAuthOptions;\n}\n\n/**\n * Node.js-specific API client for Google services.\n *\n * This client provides comprehensive authentication for Google API requests in\n * Node.js environments, leveraging the full capabilities of the google-auth-library.\n * It supports three authentication methods with the following priority:\n *\n * 1. **API Key Authentication**: Simple key-based authentication suitable for\n * public APIs and development environments.\n *\n * 2. **Service Account Credentials**: OAuth2-based authentication using GCP\n * service account keys. The client automatically handles token generation\n * and caching using a web-compatible implementation.\n *\n * 3. **Google Auth Library**: Advanced authentication using google-auth-library,\n * supporting Application Default Credentials (ADC), custom scopes, and\n * various credential sources.\n *\n * The client follows this authentication priority:\n * 1. Explicit `apiKey` parameter\n * 2. `GOOGLE_API_KEY` environment variable\n * 3. Explicit `credentials` parameter\n * 4. `GOOGLE_CLOUD_CREDENTIALS` environment variable\n * 5. `googleAuthOptions` parameter\n * 6. Application Default Credentials (if googleAuthOptions is provided without explicit credentials)\n *\n * @extends ApiClient\n *\n * @example\n * ```typescript\n * // Using API key\n * const client = new NodeApiClient({\n * apiKey: 'your-api-key'\n * });\n *\n * // Using service account credentials\n * const client = new NodeApiClient({\n * credentials: {\n * type: \"service_account\",\n * project_id: \"my-project\",\n * private_key_id: \"key-id\",\n * private_key: \"-----BEGIN PRIVATE KEY-----\\n...\",\n * client_email: \"service-account@project.iam.gserviceaccount.com\",\n * // ... other required fields\n * }\n * });\n *\n * // Using Google Auth with custom scopes\n * const client = new NodeApiClient({\n * googleAuthOptions: {\n * scopes: ['https://www.googleapis.com/auth/cloud-platform'],\n * keyFilename: '/path/to/service-account-key.json'\n * }\n * });\n *\n * // Using Application Default Credentials\n * const client = new NodeApiClient({\n * googleAuthOptions: {}\n * });\n *\n * // Using environment variables\n * // Set GOOGLE_API_KEY or GOOGLE_CLOUD_CREDENTIALS\n * const client = new NodeApiClient();\n *\n * // Make authenticated requests\n * const request = new Request('https://api.google.com/...');\n * const response = await client.fetch(request);\n * ```\n *\n * @remarks\n * - API keys are added via the `X-Goog-Api-Key` header\n * - Service account tokens are added via the `Authorization` header with Bearer scheme\n * - Google Auth headers are automatically generated and added by google-auth-library\n * - Tokens are automatically cached and refreshed as needed\n * - For web/edge environments without google-auth-library, use WebApiClient instead\n *\n * @see {@link WebApiClient} for web-compatible authentication without google-auth-library\n * @see {@link GCPCredentials} for service account credential structure\n * @see {@link GoogleAuthOptions} for advanced authentication configuration\n */\nexport class NodeApiClient extends ApiClient {\n hasApiKey(): boolean {\n return typeof this.apiKey === \"string\" && this.apiKey !== \"\";\n }\n\n async getProjectId(): Promise<string> {\n if (typeof this.credentials !== \"undefined\") {\n return this.credentials.project_id;\n } else if (typeof this.googleAuth !== \"undefined\") {\n return this.googleAuth.getProjectId();\n } else {\n return super.getProjectId();\n }\n }\n\n /**\n * The Google API key used for authentication, if provided.\n *\n * This value is resolved from either the constructor parameter or the\n * `GOOGLE_API_KEY` environment variable.\n *\n * @protected\n */\n protected apiKey?: string;\n\n /**\n * The normalized GCP service account credentials, if provided.\n *\n * This value is resolved from either the constructor parameter or the\n * `GOOGLE_CLOUD_CREDENTIALS` environment variable, and is normalized\n * to ensure immutability.\n *\n * @protected\n */\n protected credentials?: GCPCredentials;\n\n /**\n * The Google Auth instance for advanced authentication, if configured.\n *\n * This instance is created when `googleAuthOptions` is provided and\n * handles Application Default Credentials, custom scopes, and other\n * advanced authentication scenarios.\n *\n * @protected\n */\n protected googleAuth?: GoogleAuth;\n\n /**\n * Creates a new NodeApiClient instance.\n *\n * The constructor initializes authentication credentials by checking:\n * 1. Explicit parameters passed to the constructor\n * 2. Environment variables (`GOOGLE_API_KEY`, `GOOGLE_CLOUD_CREDENTIALS`)\n * 3. Application Default Credentials (if googleAuthOptions is provided)\n *\n * Credentials are normalized and frozen to prevent accidental modification.\n * The GoogleAuth instance is lazily initialized only when googleAuthOptions\n * is provided.\n *\n * @param params - Configuration parameters for the client. Defaults to an empty object.\n *\n * @example\n * ```typescript\n * // Minimal configuration (uses environment variables or ADC)\n * const client = new NodeApiClient();\n *\n * // With explicit API key\n * const client = new WebApiClient({\n * apiKey: 'your-api-key'\n * });\n *\n * // With service account credentials as JSON string\n * const client = new WebApiClient({\n * credentials: '{\"type\":\"service_account\",...}'\n * });\n *\n * // With service account credentials as object\n * const client = new NodeApiClient({\n * credentials: {\n * type: \"service_account\",\n * // ... other fields\n * }\n * });\n *\n * // With Google Auth options\n * const client = new NodeApiClient({\n * googleAuthOptions: {\n * scopes: ['https://www.googleapis.com/auth/cloud-platform'],\n * projectId: 'my-project'\n * }\n * });\n * ```\n */\n constructor(protected params: NodeApiClientParams = {}) {\n super();\n\n this.apiKey = params.apiKey ?? getEnvironmentVariable(\"GOOGLE_API_KEY\");\n this.credentials = iife(() => {\n if (params.credentials) {\n return normalizeGCPCredentials(params.credentials);\n }\n const credentialsVar = getEnvironmentVariable(\"GOOGLE_CLOUD_CREDENTIALS\");\n if (credentialsVar) {\n return normalizeGCPCredentials(credentialsVar);\n }\n return undefined;\n });\n this.googleAuth = iife(() => {\n if (params.googleAuthOptions) {\n return new GoogleAuth(params.googleAuthOptions);\n }\n if (!this.apiKey && !this.credentials) {\n return new GoogleAuth();\n }\n return undefined;\n });\n }\n\n /**\n * Executes an HTTP request with appropriate Google API authentication.\n *\n * This method adds authentication headers to the request based on the\n * configured authentication method, following this priority:\n *\n * 1. If an API key is configured, adds the `X-Goog-Api-Key` header\n * 2. If service account credentials are configured, generates an access token\n * and adds it via the `Authorization` header with Bearer scheme\n * 3. If Google Auth is configured, uses google-auth-library to generate\n * appropriate authentication headers (may include Authorization, x-goog-user-project, etc.)\n *\n * The authentication priority ensures that explicit API keys take precedence,\n * followed by service account credentials, and finally Google Auth options.\n *\n * @param request - The HTTP request to execute. Headers will be modified\n * in-place to include authentication information.\n * @returns A Promise that resolves to the HTTP response\n *\n * @throws {AuthError} If service account authentication fails (e.g., invalid\n * credentials, network error, or token generation failure)\n * @throws {Error} If Google Auth authentication fails (e.g., missing credentials,\n * invalid configuration, or ADC not available)\n *\n * @example\n * ```typescript\n * const client = new NodeApiClient({ apiKey: 'your-key' });\n * const request = new Request('https://generativelanguage.googleapis.com/v1/models');\n * const response = await client.fetch(request);\n * const data = await response.json();\n * ```\n *\n * @remarks\n * - The request object is modified in-place by adding headers\n * - Service account tokens are automatically cached and refreshed\n * - Google Auth tokens are managed by google-auth-library with automatic refresh\n * - Only one authentication method is used per request (based on priority)\n * - Google Auth may add multiple headers depending on the authentication type\n */\n async fetch(request: Request): Promise<Response> {\n if (this.apiKey) {\n request.headers.set(GOOGLE_API_KEY_HEADER, this.apiKey);\n } else if (this.credentials) {\n request.headers.set(\n GCP_API_KEY_HEADER,\n `Bearer ${getGCPCredentialsAccessToken(this.credentials)}`\n );\n } else if (this.googleAuth) {\n const authHeaders = await this.googleAuth.getRequestHeaders(request.url);\n authHeaders.forEach((value, key) => {\n if (value !== null) {\n request.headers.set(key, value);\n }\n });\n }\n return fetch(request);\n }\n}\n\n/**\n * Ensures that Google Auth options include required OAuth2 scopes.\n *\n * This utility function validates and augments GoogleAuthOptions to ensure\n * that all required OAuth2 scopes are present. It handles three scenarios:\n *\n * 1. **No auth options provided**: Creates new options with required scopes\n * 2. **Auth options without scopes**: Adds required scopes to existing options\n * 3. **Auth options with scopes**: Validates that all required scopes are present\n *\n * This is particularly useful when working with Google APIs that require specific\n * scopes for access, ensuring that authentication is properly configured before\n * making API requests.\n *\n * @param authOptions - The existing Google Auth options to validate/augment.\n * Can be undefined or an empty object.\n * @param requiredScopes - Array of OAuth2 scope URLs that must be present.\n * These are typically Google API scope URLs like\n * 'https://www.googleapis.com/auth/cloud-platform'\n * @returns The validated/augmented GoogleAuthOptions with all required scopes\n *\n * @throws {Error} If authOptions already has scopes but is missing any of the\n * required scopes. This prevents accidental scope reduction that\n * could break API access.\n *\n * @example\n * ```typescript\n * // Create new options with required scopes\n * const options = ensureAuthScopes(undefined, [\n * 'https://www.googleapis.com/auth/cloud-platform'\n * ]);\n * // Result: { scopes: ['https://www.googleapis.com/auth/cloud-platform'] }\n *\n * // Add scopes to existing options\n * const options = ensureAuthScopes(\n * { projectId: 'my-project' },\n * ['https://www.googleapis.com/auth/cloud-platform']\n * );\n * // Result: { projectId: 'my-project', scopes: [...] }\n *\n * // Validate existing scopes\n * const options = ensureAuthScopes(\n * { scopes: ['https://www.googleapis.com/auth/cloud-platform'] },\n * ['https://www.googleapis.com/auth/cloud-platform']\n * );\n * // Result: Original options (validation passed)\n *\n * // Error case - missing required scope\n * try {\n * ensureAuthScopes(\n * { scopes: ['https://www.googleapis.com/auth/userinfo.email'] },\n * ['https://www.googleapis.com/auth/cloud-platform']\n * );\n * } catch (error) {\n * // Error: Invalid auth scopes. Scopes must include ...\n * }\n * ```\n *\n * @remarks\n * - Scopes can be provided as a string or array of strings in GoogleAuthOptions\n * - The function normalizes single-string scopes to arrays for validation\n * - Required scopes are not automatically added if existing scopes are present;\n * instead, an error is thrown to prevent unintended scope changes\n * - This function does not modify the original authOptions object\n *\n * @see https://developers.google.com/identity/protocols/oauth2/scopes\n * @see {@link GoogleAuthOptions} for the full authentication configuration interface\n */\nexport function ensureAuthScopes(\n authOptions: GoogleAuthOptions,\n requiredScopes: string[]\n): GoogleAuthOptions {\n if (!authOptions) {\n return { scopes: requiredScopes };\n } else if (!authOptions.scopes) {\n return { ...authOptions, scopes: requiredScopes };\n } else {\n const existingScopes = Array.isArray(authOptions.scopes)\n ? authOptions.scopes\n : [authOptions.scopes];\n const missingScopes = requiredScopes.filter(\n (scope) => !existingScopes.includes(scope)\n );\n if (missingScopes.length > 0) {\n throw new ConfigurationError(\n `Invalid auth scopes. Scopes must include ${requiredScopes.join(\", \")}`\n );\n }\n }\n return authOptions;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkJA,IAAa,gBAAb,cAAmC,UAAU;CAC3C,YAAqB;AACnB,SAAO,OAAO,KAAK,WAAW,YAAY,KAAK,WAAW;CAC3D;CAED,MAAM,eAAgC;AACpC,MAAI,OAAO,KAAK,gBAAgB,YAC9B,QAAO,KAAK,YAAY;WACf,OAAO,KAAK,eAAe,YACpC,QAAO,KAAK,WAAW,cAAc;MAErC,QAAO,MAAM,cAAc;CAE9B;;;;;;;;;CAUD,AAAU;;;;;;;;;;CAWV,AAAU;;;;;;;;;;CAWV,AAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgDV,YAAsBA,SAA8B,CAAE,GAAE;EACtD,OAAO;EADa;EAGpB,KAAK,SAAS,OAAO,UAAU,uBAAuB,iBAAiB;EACvE,KAAK,cAAc,KAAK,MAAM;AAC5B,OAAI,OAAO,YACT,QAAO,wBAAwB,OAAO,YAAY;GAEpD,MAAM,iBAAiB,uBAAuB,2BAA2B;AACzE,OAAI,eACF,QAAO,wBAAwB,eAAe;AAEhD,UAAO;EACR,EAAC;EACF,KAAK,aAAa,KAAK,MAAM;AAC3B,OAAI,OAAO,kBACT,QAAO,IAAI,WAAW,OAAO;AAE/B,OAAI,CAAC,KAAK,UAAU,CAAC,KAAK,YACxB,QAAO,IAAI;AAEb,UAAO;EACR,EAAC;CACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyCD,MAAM,MAAMC,SAAqC;AAC/C,MAAI,KAAK,QACP,QAAQ,QAAQ,IAAI,uBAAuB,KAAK,OAAO;WAC9C,KAAK,aACd,QAAQ,QAAQ,IACd,oBACA,CAAC,OAAO,EAAE,6BAA6B,KAAK,YAAY,EAAE,CAC3D;WACQ,KAAK,YAAY;GAC1B,MAAM,cAAc,MAAM,KAAK,WAAW,kBAAkB,QAAQ,IAAI;GACxE,YAAY,QAAQ,CAAC,OAAO,QAAQ;AAClC,QAAI,UAAU,MACZ,QAAQ,QAAQ,IAAI,KAAK,MAAM;GAElC,EAAC;EACH;AACD,SAAO,MAAM,QAAQ;CACtB;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsED,SAAgB,iBACdC,aACAC,gBACmB;AACnB,KAAI,CAAC,YACH,QAAO,EAAE,QAAQ,eAAgB;UACxB,CAAC,YAAY,OACtB,QAAO;EAAE,GAAG;EAAa,QAAQ;CAAgB;MAC5C;EACL,MAAM,iBAAiB,MAAM,QAAQ,YAAY,OAAO,GACpD,YAAY,SACZ,CAAC,YAAY,MAAO;EACxB,MAAM,gBAAgB,eAAe,OACnC,CAAC,UAAU,CAAC,eAAe,SAAS,MAAM,CAC3C;AACD,MAAI,cAAc,SAAS,EACzB,OAAM,IAAI,mBACR,CAAC,yCAAyC,EAAE,eAAe,KAAK,KAAK,EAAE;CAG5E;AACD,QAAO;AACR"}
|
|
1
|
+
{"version":3,"file":"node.js","names":[],"sources":["../../src/clients/node.ts"],"sourcesContent":["import { GoogleAuth, type GoogleAuthOptions } from \"google-auth-library\";\nimport { getEnvironmentVariable } from \"@langchain/core/utils/env\";\nimport { GCP_API_KEY_HEADER, GOOGLE_API_KEY_HEADER } from \"../const.js\";\nimport { ApiClient } from \"./index.js\";\nimport {\n GCPCredentials,\n getGCPCredentialsAccessToken,\n normalizeGCPCredentials,\n} from \"../utils/gcp-auth.js\";\nimport { ConfigurationError } from \"../utils/errors.js\";\nimport { iife } from \"../utils/misc.js\";\n\n/**\n * Configuration parameters for the NodeApiClient.\n *\n * This interface defines the authentication options available for Node.js-based\n * API clients. Authentication can be provided via an API key, GCP service\n * account credentials, or advanced Google Auth options. The client will\n * automatically check environment variables if explicit values are not provided.\n *\n * @interface\n */\nexport interface NodeApiClientParams {\n /**\n * Google API key for authentication.\n *\n * If not provided, the client will attempt to read from the\n * `GOOGLE_API_KEY` environment variable.\n *\n * @see https://cloud.google.com/docs/authentication/api-keys\n */\n apiKey?: string;\n\n /**\n * GCP service account credentials for authentication.\n *\n * Can be provided as either:\n * - A JSON string containing the service account key\n * - A GCPCredentials object\n *\n * If not provided, the client will attempt to read from the\n * `GOOGLE_CLOUD_CREDENTIALS` environment variable.\n *\n * @see https://cloud.google.com/iam/docs/creating-managing-service-account-keys\n */\n credentials?: string | GCPCredentials;\n\n /**\n * Google Auth options configuration.\n *\n * Provides fine-grained control over authentication behavior using the\n * google-auth-library. This option enables:\n * - Custom OAuth2 scopes\n * - Application Default Credentials (ADC)\n * - Impersonation and delegation\n * - Custom credential sources\n *\n * When provided, this takes precedence over simple credential-based auth\n * but is lower priority than API key authentication.\n *\n * @see https://github.com/googleapis/google-auth-library-nodejs\n * @see https://cloud.google.com/docs/authentication/application-default-credentials\n */\n googleAuthOptions?: GoogleAuthOptions;\n}\n\n/**\n * Node.js-specific API client for Google services.\n *\n * This client provides comprehensive authentication for Google API requests in\n * Node.js environments, leveraging the full capabilities of the google-auth-library.\n * It supports three authentication methods with the following priority:\n *\n * 1. **API Key Authentication**: Simple key-based authentication suitable for\n * public APIs and development environments.\n *\n * 2. **Service Account Credentials**: OAuth2-based authentication using GCP\n * service account keys. The client automatically handles token generation\n * and caching using a web-compatible implementation.\n *\n * 3. **Google Auth Library**: Advanced authentication using google-auth-library,\n * supporting Application Default Credentials (ADC), custom scopes, and\n * various credential sources.\n *\n * The client follows this authentication priority:\n * 1. Explicit `apiKey` parameter\n * 2. `GOOGLE_API_KEY` environment variable\n * 3. Explicit `credentials` parameter\n * 4. `GOOGLE_CLOUD_CREDENTIALS` environment variable\n * 5. `googleAuthOptions` parameter\n * 6. Application Default Credentials (if googleAuthOptions is provided without explicit credentials)\n *\n * @extends ApiClient\n *\n * @example\n * ```typescript\n * // Using API key\n * const client = new NodeApiClient({\n * apiKey: 'your-api-key'\n * });\n *\n * // Using service account credentials\n * const client = new NodeApiClient({\n * credentials: {\n * type: \"service_account\",\n * project_id: \"my-project\",\n * private_key_id: \"key-id\",\n * private_key: \"-----BEGIN PRIVATE KEY-----\\n...\",\n * client_email: \"service-account@project.iam.gserviceaccount.com\",\n * // ... other required fields\n * }\n * });\n *\n * // Using Google Auth with custom scopes\n * const client = new NodeApiClient({\n * googleAuthOptions: {\n * scopes: ['https://www.googleapis.com/auth/cloud-platform'],\n * keyFilename: '/path/to/service-account-key.json'\n * }\n * });\n *\n * // Using Application Default Credentials\n * const client = new NodeApiClient({\n * googleAuthOptions: {}\n * });\n *\n * // Using environment variables\n * // Set GOOGLE_API_KEY or GOOGLE_CLOUD_CREDENTIALS\n * const client = new NodeApiClient();\n *\n * // Make authenticated requests\n * const request = new Request('https://api.google.com/...');\n * const response = await client.fetch(request);\n * ```\n *\n * @remarks\n * - API keys are added via the `X-Goog-Api-Key` header\n * - Service account tokens are added via the `Authorization` header with Bearer scheme\n * - Google Auth headers are automatically generated and added by google-auth-library\n * - Tokens are automatically cached and refreshed as needed\n * - For web/edge environments without google-auth-library, use WebApiClient instead\n *\n * @see {@link WebApiClient} for web-compatible authentication without google-auth-library\n * @see {@link GCPCredentials} for service account credential structure\n * @see {@link GoogleAuthOptions} for advanced authentication configuration\n */\nexport class NodeApiClient extends ApiClient {\n hasApiKey(): boolean {\n return typeof this.apiKey === \"string\" && this.apiKey !== \"\";\n }\n\n async getProjectId(): Promise<string> {\n if (typeof this.credentials !== \"undefined\") {\n return this.credentials.project_id;\n } else if (typeof this.googleAuth !== \"undefined\") {\n return this.googleAuth.getProjectId();\n } else {\n return super.getProjectId();\n }\n }\n\n /**\n * The Google API key used for authentication, if provided.\n *\n * This value is resolved from either the constructor parameter or the\n * `GOOGLE_API_KEY` environment variable.\n *\n * @protected\n */\n protected apiKey?: string;\n\n /**\n * The normalized GCP service account credentials, if provided.\n *\n * This value is resolved from either the constructor parameter or the\n * `GOOGLE_CLOUD_CREDENTIALS` environment variable, and is normalized\n * to ensure immutability.\n *\n * @protected\n */\n protected credentials?: GCPCredentials;\n\n /**\n * The Google Auth instance for advanced authentication, if configured.\n *\n * This instance is created when `googleAuthOptions` is provided and\n * handles Application Default Credentials, custom scopes, and other\n * advanced authentication scenarios.\n *\n * @protected\n */\n protected googleAuth?: GoogleAuth;\n\n /**\n * Creates a new NodeApiClient instance.\n *\n * The constructor initializes authentication credentials by checking:\n * 1. Explicit parameters passed to the constructor\n * 2. Environment variables (`GOOGLE_API_KEY`, `GOOGLE_CLOUD_CREDENTIALS`)\n * 3. Application Default Credentials (if googleAuthOptions is provided)\n *\n * Credentials are normalized and frozen to prevent accidental modification.\n * The GoogleAuth instance is lazily initialized only when googleAuthOptions\n * is provided.\n *\n * @param params - Configuration parameters for the client. Defaults to an empty object.\n *\n * @example\n * ```typescript\n * // Minimal configuration (uses environment variables or ADC)\n * const client = new NodeApiClient();\n *\n * // With explicit API key\n * const client = new WebApiClient({\n * apiKey: 'your-api-key'\n * });\n *\n * // With service account credentials as JSON string\n * const client = new WebApiClient({\n * credentials: '{\"type\":\"service_account\",...}'\n * });\n *\n * // With service account credentials as object\n * const client = new NodeApiClient({\n * credentials: {\n * type: \"service_account\",\n * // ... other fields\n * }\n * });\n *\n * // With Google Auth options\n * const client = new NodeApiClient({\n * googleAuthOptions: {\n * scopes: ['https://www.googleapis.com/auth/cloud-platform'],\n * projectId: 'my-project'\n * }\n * });\n * ```\n */\n constructor(protected params: NodeApiClientParams = {}) {\n super();\n\n this.apiKey = params.apiKey ?? getEnvironmentVariable(\"GOOGLE_API_KEY\");\n this.credentials = iife(() => {\n if (params.credentials) {\n return normalizeGCPCredentials(params.credentials);\n }\n const credentialsVar = getEnvironmentVariable(\"GOOGLE_CLOUD_CREDENTIALS\");\n if (credentialsVar) {\n return normalizeGCPCredentials(credentialsVar);\n }\n return undefined;\n });\n this.googleAuth = iife(() => {\n if (params.googleAuthOptions) {\n return new GoogleAuth(params.googleAuthOptions);\n }\n if (!this.apiKey && !this.credentials) {\n return new GoogleAuth();\n }\n return undefined;\n });\n }\n\n /**\n * Executes an HTTP request with appropriate Google API authentication.\n *\n * This method adds authentication headers to the request based on the\n * configured authentication method, following this priority:\n *\n * 1. If an API key is configured, adds the `X-Goog-Api-Key` header\n * 2. If service account credentials are configured, generates an access token\n * and adds it via the `Authorization` header with Bearer scheme\n * 3. If Google Auth is configured, uses google-auth-library to generate\n * appropriate authentication headers (may include Authorization, x-goog-user-project, etc.)\n *\n * The authentication priority ensures that explicit API keys take precedence,\n * followed by service account credentials, and finally Google Auth options.\n *\n * @param request - The HTTP request to execute. Headers will be modified\n * in-place to include authentication information.\n * @returns A Promise that resolves to the HTTP response\n *\n * @throws {AuthError} If service account authentication fails (e.g., invalid\n * credentials, network error, or token generation failure)\n * @throws {Error} If Google Auth authentication fails (e.g., missing credentials,\n * invalid configuration, or ADC not available)\n *\n * @example\n * ```typescript\n * const client = new NodeApiClient({ apiKey: 'your-key' });\n * const request = new Request('https://generativelanguage.googleapis.com/v1/models');\n * const response = await client.fetch(request);\n * const data = await response.json();\n * ```\n *\n * @remarks\n * - The request object is modified in-place by adding headers\n * - Service account tokens are automatically cached and refreshed\n * - Google Auth tokens are managed by google-auth-library with automatic refresh\n * - Only one authentication method is used per request (based on priority)\n * - Google Auth may add multiple headers depending on the authentication type\n */\n async fetch(request: Request): Promise<Response> {\n if (this.apiKey) {\n request.headers.set(GOOGLE_API_KEY_HEADER, this.apiKey);\n } else if (this.credentials) {\n request.headers.set(\n GCP_API_KEY_HEADER,\n `Bearer ${getGCPCredentialsAccessToken(this.credentials)}`\n );\n } else if (this.googleAuth) {\n const authHeaders = await this.googleAuth.getRequestHeaders(request.url);\n authHeaders.forEach((value, key) => {\n if (value !== null) {\n request.headers.set(key, value);\n }\n });\n }\n return fetch(request);\n }\n}\n\n/**\n * Ensures that Google Auth options include required OAuth2 scopes.\n *\n * This utility function validates and augments GoogleAuthOptions to ensure\n * that all required OAuth2 scopes are present. It handles three scenarios:\n *\n * 1. **No auth options provided**: Creates new options with required scopes\n * 2. **Auth options without scopes**: Adds required scopes to existing options\n * 3. **Auth options with scopes**: Validates that all required scopes are present\n *\n * This is particularly useful when working with Google APIs that require specific\n * scopes for access, ensuring that authentication is properly configured before\n * making API requests.\n *\n * @param authOptions - The existing Google Auth options to validate/augment.\n * Can be undefined or an empty object.\n * @param requiredScopes - Array of OAuth2 scope URLs that must be present.\n * These are typically Google API scope URLs like\n * 'https://www.googleapis.com/auth/cloud-platform'\n * @returns The validated/augmented GoogleAuthOptions with all required scopes\n *\n * @throws {Error} If authOptions already has scopes but is missing any of the\n * required scopes. This prevents accidental scope reduction that\n * could break API access.\n *\n * @example\n * ```typescript\n * // Create new options with required scopes\n * const options = ensureAuthScopes(undefined, [\n * 'https://www.googleapis.com/auth/cloud-platform'\n * ]);\n * // Result: { scopes: ['https://www.googleapis.com/auth/cloud-platform'] }\n *\n * // Add scopes to existing options\n * const options = ensureAuthScopes(\n * { projectId: 'my-project' },\n * ['https://www.googleapis.com/auth/cloud-platform']\n * );\n * // Result: { projectId: 'my-project', scopes: [...] }\n *\n * // Validate existing scopes\n * const options = ensureAuthScopes(\n * { scopes: ['https://www.googleapis.com/auth/cloud-platform'] },\n * ['https://www.googleapis.com/auth/cloud-platform']\n * );\n * // Result: Original options (validation passed)\n *\n * // Error case - missing required scope\n * try {\n * ensureAuthScopes(\n * { scopes: ['https://www.googleapis.com/auth/userinfo.email'] },\n * ['https://www.googleapis.com/auth/cloud-platform']\n * );\n * } catch (error) {\n * // Error: Invalid auth scopes. Scopes must include ...\n * }\n * ```\n *\n * @remarks\n * - Scopes can be provided as a string or array of strings in GoogleAuthOptions\n * - The function normalizes single-string scopes to arrays for validation\n * - Required scopes are not automatically added if existing scopes are present;\n * instead, an error is thrown to prevent unintended scope changes\n * - This function does not modify the original authOptions object\n *\n * @see https://developers.google.com/identity/protocols/oauth2/scopes\n * @see {@link GoogleAuthOptions} for the full authentication configuration interface\n */\nexport function ensureAuthScopes(\n authOptions: GoogleAuthOptions,\n requiredScopes: string[]\n): GoogleAuthOptions {\n if (!authOptions) {\n return { scopes: requiredScopes };\n } else if (!authOptions.scopes) {\n return { ...authOptions, scopes: requiredScopes };\n } else {\n const existingScopes = Array.isArray(authOptions.scopes)\n ? authOptions.scopes\n : [authOptions.scopes];\n const missingScopes = requiredScopes.filter(\n (scope) => !existingScopes.includes(scope)\n );\n if (missingScopes.length > 0) {\n throw new ConfigurationError(\n `Invalid auth scopes. Scopes must include ${requiredScopes.join(\", \")}`\n );\n }\n }\n return authOptions;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkJA,IAAa,gBAAb,cAAmC,UAAU;CAC3C,YAAqB;AACnB,SAAO,OAAO,KAAK,WAAW,YAAY,KAAK,WAAW;;CAG5D,MAAM,eAAgC;AACpC,MAAI,OAAO,KAAK,gBAAgB,YAC9B,QAAO,KAAK,YAAY;WACf,OAAO,KAAK,eAAe,YACpC,QAAO,KAAK,WAAW,cAAc;MAErC,QAAO,MAAM,cAAc;;;;;;;;;;CAY/B,AAAU;;;;;;;;;;CAWV,AAAU;;;;;;;;;;CAWV,AAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgDV,YAAY,AAAU,SAA8B,EAAE,EAAE;AACtD,SAAO;EADa;AAGpB,OAAK,SAAS,OAAO,UAAU,uBAAuB,iBAAiB;AACvE,OAAK,cAAc,WAAW;AAC5B,OAAI,OAAO,YACT,QAAO,wBAAwB,OAAO,YAAY;GAEpD,MAAM,iBAAiB,uBAAuB,2BAA2B;AACzE,OAAI,eACF,QAAO,wBAAwB,eAAe;IAGhD;AACF,OAAK,aAAa,WAAW;AAC3B,OAAI,OAAO,kBACT,QAAO,IAAI,WAAW,OAAO,kBAAkB;AAEjD,OAAI,CAAC,KAAK,UAAU,CAAC,KAAK,YACxB,QAAO,IAAI,YAAY;IAGzB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0CJ,MAAM,MAAM,SAAqC;AAC/C,MAAI,KAAK,OACP,SAAQ,QAAQ,IAAI,uBAAuB,KAAK,OAAO;WAC9C,KAAK,YACd,SAAQ,QAAQ,IACd,oBACA,UAAU,6BAA6B,KAAK,YAAY,GACzD;WACQ,KAAK,WAEd,EADoB,MAAM,KAAK,WAAW,kBAAkB,QAAQ,IAAI,EAC5D,SAAS,OAAO,QAAQ;AAClC,OAAI,UAAU,KACZ,SAAQ,QAAQ,IAAI,KAAK,MAAM;IAEjC;AAEJ,SAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwEzB,SAAgB,iBACd,aACA,gBACmB;AACnB,KAAI,CAAC,YACH,QAAO,EAAE,QAAQ,gBAAgB;UACxB,CAAC,YAAY,OACtB,QAAO;EAAE,GAAG;EAAa,QAAQ;EAAgB;MAC5C;EACL,MAAM,iBAAiB,MAAM,QAAQ,YAAY,OAAO,GACpD,YAAY,SACZ,CAAC,YAAY,OAAO;AAIxB,MAHsB,eAAe,QAClC,UAAU,CAAC,eAAe,SAAS,MAAM,CAC3C,CACiB,SAAS,EACzB,OAAM,IAAI,mBACR,4CAA4C,eAAe,KAAK,KAAK,GACtE;;AAGL,QAAO"}
|
package/dist/const.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"const.cjs","names":[],"sources":["../src/const.ts"],"sourcesContent":["export const GOOGLE_API_KEY_HEADER = \"x-goog-api-key\";\n\nexport const GCP_API_KEY_HEADER = \"Authorization\";\n\nexport const GENERATIVE_AI_AUTH_SCOPES = [\n \"https://www.googleapis.com/auth/generative-language\",\n];\n\nexport const VERTEX_AI_AUTH_SCOPES = [\n \"https://www.googleapis.com/auth/cloud-platform\",\n];\n"],"mappings":";;AAAA,MAAa,wBAAwB;AAErC,MAAa,qBAAqB;AAElC,MAAa,4BAA4B,CACvC,
|
|
1
|
+
{"version":3,"file":"const.cjs","names":[],"sources":["../src/const.ts"],"sourcesContent":["export const GOOGLE_API_KEY_HEADER = \"x-goog-api-key\";\n\nexport const GCP_API_KEY_HEADER = \"Authorization\";\n\nexport const GENERATIVE_AI_AUTH_SCOPES = [\n \"https://www.googleapis.com/auth/generative-language\",\n];\n\nexport const VERTEX_AI_AUTH_SCOPES = [\n \"https://www.googleapis.com/auth/cloud-platform\",\n];\n"],"mappings":";;AAAA,MAAa,wBAAwB;AAErC,MAAa,qBAAqB;AAElC,MAAa,4BAA4B,CACvC,sDACD;AAED,MAAa,wBAAwB,CACnC,iDACD"}
|
package/dist/const.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"const.js","names":[],"sources":["../src/const.ts"],"sourcesContent":["export const GOOGLE_API_KEY_HEADER = \"x-goog-api-key\";\n\nexport const GCP_API_KEY_HEADER = \"Authorization\";\n\nexport const GENERATIVE_AI_AUTH_SCOPES = [\n \"https://www.googleapis.com/auth/generative-language\",\n];\n\nexport const VERTEX_AI_AUTH_SCOPES = [\n \"https://www.googleapis.com/auth/cloud-platform\",\n];\n"],"mappings":";AAAA,MAAa,wBAAwB;AAErC,MAAa,qBAAqB;AAElC,MAAa,4BAA4B,CACvC,
|
|
1
|
+
{"version":3,"file":"const.js","names":[],"sources":["../src/const.ts"],"sourcesContent":["export const GOOGLE_API_KEY_HEADER = \"x-goog-api-key\";\n\nexport const GCP_API_KEY_HEADER = \"Authorization\";\n\nexport const GENERATIVE_AI_AUTH_SCOPES = [\n \"https://www.googleapis.com/auth/generative-language\",\n];\n\nexport const VERTEX_AI_AUTH_SCOPES = [\n \"https://www.googleapis.com/auth/cloud-platform\",\n];\n"],"mappings":";AAAA,MAAa,wBAAwB;AAErC,MAAa,qBAAqB;AAElC,MAAa,4BAA4B,CACvC,sDACD;AAED,MAAa,wBAAwB,CACnC,iDACD"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
|
|
2
1
|
const require_misc = require('../utils/misc.cjs');
|
|
3
2
|
const require_errors = require('../utils/errors.cjs');
|
|
4
|
-
|
|
3
|
+
let _langchain_core_messages = require("@langchain/core/messages");
|
|
5
4
|
|
|
6
5
|
//#region src/converters/messages.ts
|
|
7
6
|
/**
|
|
@@ -17,7 +16,7 @@ const geminiContentBlockConverter = {
|
|
|
17
16
|
return { text: block.text };
|
|
18
17
|
},
|
|
19
18
|
fromStandardImageBlock(block) {
|
|
20
|
-
if ((0,
|
|
19
|
+
if ((0, _langchain_core_messages.isDataContentBlock)(block)) {
|
|
21
20
|
if (block.source_type === "base64") {
|
|
22
21
|
if (!block.mime_type) throw new require_errors.InvalidInputError("mime_type is required for base64 image blocks");
|
|
23
22
|
const dataStr = typeof block.data === "string" ? block.data : typeof block.data === "object" && block.data !== null ? btoa(Array.from(block.data).map((byte) => String.fromCharCode(byte)).join("")) : String(block.data);
|
|
@@ -27,7 +26,7 @@ const geminiContentBlockConverter = {
|
|
|
27
26
|
} };
|
|
28
27
|
}
|
|
29
28
|
if (block.source_type === "url") {
|
|
30
|
-
const parsed = (0,
|
|
29
|
+
const parsed = (0, _langchain_core_messages.parseBase64DataUrl)({ dataUrl: block.url });
|
|
31
30
|
if (parsed) {
|
|
32
31
|
const dataStr = typeof parsed.data === "string" ? parsed.data : btoa(Array.from(parsed.data).map((byte) => String.fromCharCode(byte)).join(""));
|
|
33
32
|
return { inlineData: {
|
|
@@ -48,7 +47,7 @@ const geminiContentBlockConverter = {
|
|
|
48
47
|
throw new require_errors.InvalidInputError(`Image content blocks with source_type "${block.source_type}" are not supported for ChatGoogle. Supported source types are: "base64", "url", "id".`);
|
|
49
48
|
},
|
|
50
49
|
fromStandardAudioBlock(block) {
|
|
51
|
-
if ((0,
|
|
50
|
+
if ((0, _langchain_core_messages.isDataContentBlock)(block)) {
|
|
52
51
|
if (block.source_type === "base64") {
|
|
53
52
|
if (!block.mime_type) throw new require_errors.InvalidInputError("mime_type is required for base64 audio blocks");
|
|
54
53
|
const dataStr = typeof block.data === "string" ? block.data : typeof block.data === "object" && block.data !== null ? btoa(Array.from(block.data).map((byte) => String.fromCharCode(byte)).join("")) : String(block.data);
|
|
@@ -58,7 +57,7 @@ const geminiContentBlockConverter = {
|
|
|
58
57
|
} };
|
|
59
58
|
}
|
|
60
59
|
if (block.source_type === "url") {
|
|
61
|
-
const parsed = (0,
|
|
60
|
+
const parsed = (0, _langchain_core_messages.parseBase64DataUrl)({ dataUrl: block.url });
|
|
62
61
|
if (parsed) {
|
|
63
62
|
const dataStr = typeof parsed.data === "string" ? parsed.data : btoa(Array.from(parsed.data).map((byte) => String.fromCharCode(byte)).join(""));
|
|
64
63
|
return { inlineData: {
|
|
@@ -79,7 +78,7 @@ const geminiContentBlockConverter = {
|
|
|
79
78
|
throw new require_errors.InvalidInputError(`Audio content blocks with source_type "${block.source_type}" are not supported for ChatGoogle. Supported source types are: "base64", "url", "id".`);
|
|
80
79
|
},
|
|
81
80
|
fromStandardFileBlock(block) {
|
|
82
|
-
if ((0,
|
|
81
|
+
if ((0, _langchain_core_messages.isDataContentBlock)(block)) {
|
|
83
82
|
if (block.source_type === "base64") {
|
|
84
83
|
if (!block.mime_type) throw new require_errors.InvalidInputError("mime_type is required for base64 file blocks");
|
|
85
84
|
const dataStr = typeof block.data === "string" ? block.data : typeof block.data === "object" && block.data !== null ? btoa(Array.from(block.data).map((byte) => String.fromCharCode(byte)).join("")) : String(block.data);
|
|
@@ -89,7 +88,7 @@ const geminiContentBlockConverter = {
|
|
|
89
88
|
} };
|
|
90
89
|
}
|
|
91
90
|
if (block.source_type === "url") {
|
|
92
|
-
const parsed = (0,
|
|
91
|
+
const parsed = (0, _langchain_core_messages.parseBase64DataUrl)({ dataUrl: block.url });
|
|
93
92
|
if (parsed) {
|
|
94
93
|
const dataStr = typeof parsed.data === "string" ? parsed.data : btoa(Array.from(parsed.data).map((byte) => String.fromCharCode(byte)).join(""));
|
|
95
94
|
return { inlineData: {
|
|
@@ -125,21 +124,15 @@ function convertStandardDataContentBlockToGeminiPart(block) {
|
|
|
125
124
|
data: null
|
|
126
125
|
};
|
|
127
126
|
}
|
|
128
|
-
if ("mimeType" in block && "data" in block) {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
const fileUri = block.url;
|
|
138
|
-
return { fileData: {
|
|
139
|
-
mimeType,
|
|
140
|
-
fileUri
|
|
141
|
-
} };
|
|
142
|
-
} else if ("url" in block && block.url?.startsWith("data:")) {
|
|
127
|
+
if ("mimeType" in block && "data" in block) return { inlineData: {
|
|
128
|
+
mimeType: block.mimeType,
|
|
129
|
+
data: typeof block.data === "string" ? block.data : uint8arrayToString(block.data)
|
|
130
|
+
} };
|
|
131
|
+
else if ("mimeType" in block && "url" in block) return { fileData: {
|
|
132
|
+
mimeType: block.mimeType,
|
|
133
|
+
fileUri: block.url
|
|
134
|
+
} };
|
|
135
|
+
else if ("url" in block && block.url?.startsWith("data:")) {
|
|
143
136
|
const { mimeType, data } = extractMimeType(block.url);
|
|
144
137
|
if (mimeType && data) return { inlineData: {
|
|
145
138
|
mimeType,
|
|
@@ -175,12 +168,12 @@ function convertStandardContentBlockToGeminiPart(block) {
|
|
|
175
168
|
* This is intended to be called from `convertMessagesToGeminiContent`
|
|
176
169
|
*/
|
|
177
170
|
function convertStandardContentMessageToGeminiContent(message) {
|
|
178
|
-
if (
|
|
171
|
+
if (_langchain_core_messages.SystemMessage.isInstance(message)) return null;
|
|
179
172
|
let role;
|
|
180
|
-
if (
|
|
181
|
-
else if (
|
|
182
|
-
else if (
|
|
183
|
-
else if (
|
|
173
|
+
if (_langchain_core_messages.HumanMessage.isInstance(message)) role = "user";
|
|
174
|
+
else if (_langchain_core_messages.AIMessage.isInstance(message)) role = "model";
|
|
175
|
+
else if (_langchain_core_messages.ToolMessage.isInstance(message)) role = "function";
|
|
176
|
+
else if (_langchain_core_messages.ChatMessage.isInstance(message)) {
|
|
184
177
|
const msgRole = message.role.toLowerCase();
|
|
185
178
|
if (msgRole === "user" || msgRole === "human") role = "user";
|
|
186
179
|
else if (msgRole === "assistant" || msgRole === "ai" || msgRole === "model") role = "model";
|
|
@@ -189,11 +182,10 @@ function convertStandardContentMessageToGeminiContent(message) {
|
|
|
189
182
|
} else role = "user";
|
|
190
183
|
const parts = [];
|
|
191
184
|
message.contentBlocks.forEach((block) => {
|
|
192
|
-
const
|
|
193
|
-
const part = convertStandardContentBlockToGeminiPart(contentBlock);
|
|
185
|
+
const part = convertStandardContentBlockToGeminiPart(message.additional_kwargs.originalTextContentBlock || block);
|
|
194
186
|
if (part) parts.push(part);
|
|
195
187
|
});
|
|
196
|
-
if (
|
|
188
|
+
if (_langchain_core_messages.ToolMessage.isInstance(message) && message.tool_call_id) {
|
|
197
189
|
const responseContent = typeof message.content === "string" ? message.content : JSON.stringify(message.content);
|
|
198
190
|
parts.push({ functionResponse: {
|
|
199
191
|
name: message.name || "unknown",
|
|
@@ -213,7 +205,7 @@ function convertStandardContentMessageToGeminiContent(message) {
|
|
|
213
205
|
* This is intended to be called from `convertMessagesToGeminiContent`
|
|
214
206
|
*/
|
|
215
207
|
function convertLegacyContentMessageToGeminiContent(message, messages) {
|
|
216
|
-
if (
|
|
208
|
+
if (_langchain_core_messages.SystemMessage.isInstance(message)) return null;
|
|
217
209
|
/**
|
|
218
210
|
* @deprecated - This is for use by `convertLegacyContentMessageToGeminiContent` only
|
|
219
211
|
*/
|
|
@@ -253,33 +245,26 @@ function convertLegacyContentMessageToGeminiContent(message, messages) {
|
|
|
253
245
|
tif: "image/tiff"
|
|
254
246
|
};
|
|
255
247
|
try {
|
|
256
|
-
const
|
|
257
|
-
const extension = pathname.split(".").pop()?.toLowerCase().split(/[?#]/)[0];
|
|
248
|
+
const extension = new URL(url).pathname.split(".").pop()?.toLowerCase().split(/[?#]/)[0];
|
|
258
249
|
return extension ? mimeTypeMap[extension] : "application/octet-stream";
|
|
259
250
|
} catch {
|
|
260
251
|
const match = url.match(/\.([a-zA-Z0-9]+)(?:[?#]|$)/);
|
|
261
|
-
if (match)
|
|
262
|
-
const extension = match[1].toLowerCase();
|
|
263
|
-
return mimeTypeMap[extension];
|
|
264
|
-
}
|
|
252
|
+
if (match) return mimeTypeMap[match[1].toLowerCase()];
|
|
265
253
|
return "application/octet-stream";
|
|
266
254
|
}
|
|
267
255
|
}
|
|
268
256
|
function messageContentImageUrlData(content) {
|
|
269
257
|
const url = typeof content.image_url === "string" ? content.image_url : content.image_url.url;
|
|
270
258
|
if (!url) throw new require_errors.InvalidInputError("Missing image URL in image_url content block.");
|
|
271
|
-
const dataUrl = (0,
|
|
259
|
+
const dataUrl = (0, _langchain_core_messages.parseBase64DataUrl)({ dataUrl: url });
|
|
272
260
|
if (dataUrl?.data && dataUrl?.mime_type) return { inlineData: {
|
|
273
261
|
data: dataUrl.data,
|
|
274
262
|
mimeType: dataUrl.mime_type
|
|
275
263
|
} };
|
|
276
|
-
else {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
fileUri: url
|
|
281
|
-
} };
|
|
282
|
-
}
|
|
264
|
+
else return { fileData: {
|
|
265
|
+
mimeType: inferMimeTypeFromUrl(url) || "image/png",
|
|
266
|
+
fileUri: url
|
|
267
|
+
} };
|
|
283
268
|
}
|
|
284
269
|
function messageContentImageUrl(content) {
|
|
285
270
|
const ret = messageContentImageUrlData(content);
|
|
@@ -307,10 +292,10 @@ function convertLegacyContentMessageToGeminiContent(message, messages) {
|
|
|
307
292
|
return ret;
|
|
308
293
|
}
|
|
309
294
|
const role = require_misc.iife(() => {
|
|
310
|
-
if (
|
|
311
|
-
else if (
|
|
312
|
-
else if (
|
|
313
|
-
else if (
|
|
295
|
+
if (_langchain_core_messages.HumanMessage.isInstance(message)) return "user";
|
|
296
|
+
else if (_langchain_core_messages.AIMessage.isInstance(message)) return "model";
|
|
297
|
+
else if (_langchain_core_messages.ToolMessage.isInstance(message)) return "function";
|
|
298
|
+
else if (_langchain_core_messages.ChatMessage.isInstance(message)) {
|
|
314
299
|
const msgRole = message.role.toLowerCase();
|
|
315
300
|
if (msgRole === "user" || msgRole === "human") return "user";
|
|
316
301
|
else if (msgRole === "assistant" || msgRole === "ai" || msgRole === "model") return "model";
|
|
@@ -324,9 +309,9 @@ function convertLegacyContentMessageToGeminiContent(message, messages) {
|
|
|
324
309
|
} else if (Array.isArray(message.content)) {
|
|
325
310
|
for (const item of message.content) if (typeof item === "string") parts.push({ text: item });
|
|
326
311
|
else if (typeof item === "object" && item !== null) if (isMessageContentText(item)) parts.push({ text: item.text });
|
|
327
|
-
else if ((0,
|
|
312
|
+
else if ((0, _langchain_core_messages.isDataContentBlock)(item)) parts.push((0, _langchain_core_messages.convertToProviderContentBlock)(item, geminiContentBlockConverter));
|
|
328
313
|
else if (item?.type === "functionCall") {
|
|
329
|
-
const { type, functionCall
|
|
314
|
+
const { type, functionCall, ...etc } = item;
|
|
330
315
|
parts.push({
|
|
331
316
|
...etc,
|
|
332
317
|
functionCall
|
|
@@ -335,9 +320,9 @@ function convertLegacyContentMessageToGeminiContent(message, messages) {
|
|
|
335
320
|
else if (isMessageContentMedia(item)) parts.push(messageContentMedia(item));
|
|
336
321
|
else parts.push(item);
|
|
337
322
|
}
|
|
338
|
-
if (
|
|
323
|
+
if (_langchain_core_messages.ToolMessage.isInstance(message) && message.tool_call_id) {
|
|
339
324
|
const responseContent = typeof message.content === "string" ? message.content : JSON.stringify(message.content);
|
|
340
|
-
const toolCall = messages.filter(
|
|
325
|
+
const toolCall = messages.filter(_langchain_core_messages.AIMessage.isInstance).find((msg) => msg.tool_calls?.find((tc) => tc.id === message.tool_call_id));
|
|
341
326
|
if (!toolCall) throw new require_errors.ToolCallNotFoundError(message.tool_call_id);
|
|
342
327
|
parts.push({ functionResponse: {
|
|
343
328
|
name: toolCall?.name || "unknown",
|
|
@@ -390,10 +375,8 @@ const convertMessagesToGeminiContents = (messages) => {
|
|
|
390
375
|
const contents = [];
|
|
391
376
|
for (const message of messages) {
|
|
392
377
|
const content = require_misc.iife(() => {
|
|
393
|
-
|
|
394
|
-
switch (outputVersion) {
|
|
378
|
+
switch ("output_version" in message.response_metadata ? message.response_metadata?.output_version : "v0") {
|
|
395
379
|
case "v1": return convertStandardContentMessageToGeminiContent(message);
|
|
396
|
-
case "v0":
|
|
397
380
|
default: return convertLegacyContentMessageToGeminiContent(message, messages);
|
|
398
381
|
}
|
|
399
382
|
});
|
|
@@ -441,10 +424,10 @@ const convertMessagesToGeminiContents = (messages) => {
|
|
|
441
424
|
*/
|
|
442
425
|
const convertMessagesToGeminiSystemInstruction = (messages) => {
|
|
443
426
|
const systemParts = [];
|
|
444
|
-
for (const message of messages) if (
|
|
427
|
+
for (const message of messages) if (_langchain_core_messages.SystemMessage.isInstance(message)) {
|
|
445
428
|
if (message.text.trim()) systemParts.push({ text: message.text });
|
|
446
429
|
}
|
|
447
|
-
if (systemParts.length === 0) return
|
|
430
|
+
if (systemParts.length === 0) return;
|
|
448
431
|
return { parts: systemParts };
|
|
449
432
|
};
|
|
450
433
|
/**
|
|
@@ -588,8 +571,7 @@ const convertGeminiCandidateToAIMessage = (candidate) => {
|
|
|
588
571
|
const ret = [];
|
|
589
572
|
if (!groundingSupports || groundingSupports.length === 0) return [[]];
|
|
590
573
|
groundingSupports?.forEach((groundingSupport) => {
|
|
591
|
-
const
|
|
592
|
-
const partIndex = segment?.partIndex ?? 0;
|
|
574
|
+
const partIndex = (groundingSupport?.segment)?.partIndex ?? 0;
|
|
593
575
|
if (ret[partIndex]) ret[partIndex].push(groundingSupport);
|
|
594
576
|
else ret[partIndex] = [groundingSupport];
|
|
595
577
|
});
|
|
@@ -644,7 +626,7 @@ const convertGeminiCandidateToAIMessage = (candidate) => {
|
|
|
644
626
|
};
|
|
645
627
|
for (const attribute in additional_kwargs) if (additional_kwargs[attribute] === void 0) delete additional_kwargs[attribute];
|
|
646
628
|
for (const attribute in response_metadata) if (response_metadata[attribute] === void 0) delete response_metadata[attribute];
|
|
647
|
-
return new
|
|
629
|
+
return new _langchain_core_messages.AIMessage({
|
|
648
630
|
content,
|
|
649
631
|
tool_calls: toolCalls.length > 0 ? toolCalls : void 0,
|
|
650
632
|
additional_kwargs,
|
|
@@ -662,15 +644,12 @@ const convertGeminiGenerateContentResponseToUsageMetadata = (data) => {
|
|
|
662
644
|
const { modality, tokenCount } = modalityTokenCount;
|
|
663
645
|
if (typeof modality === "undefined" || typeof tokenCount === "undefined") return;
|
|
664
646
|
const modalityLc = modality.toLowerCase();
|
|
665
|
-
|
|
666
|
-
details[modalityLc] = currentCount + tokenCount;
|
|
647
|
+
details[modalityLc] = (details[modalityLc] ?? 0) + tokenCount;
|
|
667
648
|
});
|
|
668
649
|
}
|
|
669
650
|
const usageMetadata = data.usageMetadata;
|
|
670
651
|
const inputTokenCount = usageMetadata?.promptTokenCount ?? 0;
|
|
671
|
-
const
|
|
672
|
-
const thoughtsTokenCount = usageMetadata?.thoughtsTokenCount ?? 0;
|
|
673
|
-
const outputTokenCount = candidatesTokenCount + thoughtsTokenCount;
|
|
652
|
+
const outputTokenCount = (usageMetadata?.candidatesTokenCount ?? 0) + (usageMetadata?.thoughtsTokenCount ?? 0);
|
|
674
653
|
const totalTokens = usageMetadata?.totalTokenCount ?? inputTokenCount + outputTokenCount;
|
|
675
654
|
const input_token_details = {};
|
|
676
655
|
addModalityCounts(usageMetadata?.promptTokensDetails, input_token_details);
|