From 65ff733b47914608d0dbbfb0802d3aca7a957143 Mon Sep 17 00:00:00 2001 From: Bagatur Date: Mon, 23 Sep 2024 14:57:11 -0700 Subject: [PATCH 1/6] aws[patch]: support AWS_... env vars --- .../src/chat_models/bedrock/web.ts | 46 ++++++++++++++----- .../src/utils/bedrock/index.ts | 4 ++ 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/libs/langchain-community/src/chat_models/bedrock/web.ts b/libs/langchain-community/src/chat_models/bedrock/web.ts index 69a0bb42eb8b..d30a338680e1 100644 --- a/libs/langchain-community/src/chat_models/bedrock/web.ts +++ b/libs/langchain-community/src/chat_models/bedrock/web.ts @@ -183,9 +183,9 @@ export interface BedrockChatFields * * ```bash * npm install @langchain/openai - * export BEDROCK_AWS_REGION="your-aws-region" - * export BEDROCK_AWS_SECRET_ACCESS_KEY="your-aws-secret-access-key" - * export BEDROCK_AWS_ACCESS_KEY_ID="your-aws-access-key-id" + * export AWS_REGION="your-aws-region" + * export AWS_SECRET_ACCESS_KEY="your-aws-secret-access-key" + * export AWS_ACCESS_KEY_ID="your-aws-access-key-id" * ``` * * ## [Constructor args](/classes/langchain_community_chat_models_bedrock.BedrockChat.html#constructor) @@ -220,11 +220,11 @@ export interface BedrockChatFields * import { BedrockChat } from '@langchain/community/chat_models/bedrock'; * * const llm = new BedrockChat({ - * region: process.env.BEDROCK_AWS_REGION, + * region: process.env.AWS_REGION, * maxRetries: 0, * credentials: { - * secretAccessKey: process.env.BEDROCK_AWS_SECRET_ACCESS_KEY!, - * accessKeyId: process.env.BEDROCK_AWS_ACCESS_KEY_ID!, + * secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!, + * accessKeyId: process.env.AWS_ACCESS_KEY_ID!, * }, * model: "anthropic.claude-3-5-sonnet-20240620-v1:0", * temperature: 0, @@ -499,7 +499,10 @@ export class BedrockChat region: string; - credentials: CredentialType; + credentials?: CredentialType; + awsAccessKeyID?: string; + awsSecretAccessKey?: string; + awsSessionToken?: string; temperature?: number | undefined = undefined; @@ -542,8 +545,11 @@ export class BedrockChat get lc_secrets(): { [key: string]: string } | undefined { return { - "credentials.accessKeyId": "BEDROCK_AWS_ACCESS_KEY_ID", - "credentials.secretAccessKey": "BEDROCK_AWS_SECRET_ACCESS_KEY", + "credentials.accessKeyId": "AWS_ACCESS_KEY_ID", + "credentials.secretAccessKey": "AWS_SECRET_ACCESS_KEY", + awsAccessKeyId: "AWS_ACCESS_KEY_ID", + awsSecretAccessKey: "AWS_SECRET_ACCESS_KEY", + awsSessionToken: "AWS_SESSION_TOKEN", }; } @@ -585,10 +591,28 @@ export class BedrockChat } this.region = region; - const credentials = fields?.credentials; + this.awsAccessKeyID = + fields?.awsAccessKeyID || getEnvironmentVariable("AWS_ACCESS_KEY_ID"); + this.awsSecretAccessKey = + fields?.awsSecretAccessKey || + getEnvironmentVariable("AWS_SECRET_ACCESS_KEY"); + this.awsSessionToken = + fields?.awsSessionToken || getEnvironmentVariable("AWS_SESSION_TOKEN"); + const credentials = fields?.credentials ?? { + ...(this.awsAccessKeyID !== undefined && { + accessKeyID: this.awsAccessKeyID, + }), + ...(this.awsSecretAccessKey !== undefined && { + secretAccessKey: this.awsSecretAccessKey, + }), + ...(this.awsSessionToken !== undefined && { + sessionToken: this.awsSessionToken, + }), + }; + if (!credentials) { throw new Error( - "Please set the AWS credentials in the 'credentials' field." + "Please set the AWS credentials in the 'credentials' field or set env vars AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, or AWS_SESSION_TOKEN." ); } this.credentials = credentials; diff --git a/libs/langchain-community/src/utils/bedrock/index.ts b/libs/langchain-community/src/utils/bedrock/index.ts index 551787dbe6d5..1fdbfbd328fc 100644 --- a/libs/langchain-community/src/utils/bedrock/index.ts +++ b/libs/langchain-community/src/utils/bedrock/index.ts @@ -168,6 +168,10 @@ export interface BaseBedrockInput { tagSuffix: string; streamProcessingMode: "SYNCHRONOUS" | "ASYNCHRONOUS"; }; + + awsAccessKeyID?: string; + awsSecretAccessKey?: string; + awsSessionToken?: string; } type Dict = { [key: string]: unknown }; From e6905b6827afad85099a154f1cf7cfb9277bf005 Mon Sep 17 00:00:00 2001 From: Bagatur Date: Mon, 23 Sep 2024 14:58:17 -0700 Subject: [PATCH 2/6] doc --- .../src/chat_models/bedrock/index.ts | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/libs/langchain-community/src/chat_models/bedrock/index.ts b/libs/langchain-community/src/chat_models/bedrock/index.ts index 9802beffe4cb..11c7be94d85c 100644 --- a/libs/langchain-community/src/chat_models/bedrock/index.ts +++ b/libs/langchain-community/src/chat_models/bedrock/index.ts @@ -21,9 +21,9 @@ export interface BedrockChatFields * * ```bash * npm install @langchain/openai - * export BEDROCK_AWS_REGION="your-aws-region" - * export BEDROCK_AWS_SECRET_ACCESS_KEY="your-aws-secret-access-key" - * export BEDROCK_AWS_ACCESS_KEY_ID="your-aws-access-key-id" + * export AWS_REGION="your-aws-region" + * export AWS_SECRET_ACCESS_KEY="your-aws-secret-access-key" + * export AWS_ACCESS_KEY_ID="your-aws-access-key-id" * ``` * * ## [Constructor args](/classes/langchain_community_chat_models_bedrock.BedrockChat.html#constructor) @@ -60,10 +60,6 @@ export interface BedrockChatFields * const llm = new BedrockChat({ * region: process.env.BEDROCK_AWS_REGION, * maxRetries: 0, - * credentials: { - * secretAccessKey: process.env.BEDROCK_AWS_SECRET_ACCESS_KEY!, - * accessKeyId: process.env.BEDROCK_AWS_ACCESS_KEY_ID!, - * }, * model: "anthropic.claude-3-5-sonnet-20240620-v1:0", * temperature: 0, * maxTokens: undefined, From 2c1bcc4bd798cc123438a4d5907968eeb294ff9a Mon Sep 17 00:00:00 2001 From: Bagatur Date: Mon, 23 Sep 2024 15:00:40 -0700 Subject: [PATCH 3/6] docstring --- libs/langchain-community/src/chat_models/bedrock/web.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libs/langchain-community/src/chat_models/bedrock/web.ts b/libs/langchain-community/src/chat_models/bedrock/web.ts index d30a338680e1..4d17a3dc25b5 100644 --- a/libs/langchain-community/src/chat_models/bedrock/web.ts +++ b/libs/langchain-community/src/chat_models/bedrock/web.ts @@ -222,10 +222,6 @@ export interface BedrockChatFields * const llm = new BedrockChat({ * region: process.env.AWS_REGION, * maxRetries: 0, - * credentials: { - * secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!, - * accessKeyId: process.env.AWS_ACCESS_KEY_ID!, - * }, * model: "anthropic.claude-3-5-sonnet-20240620-v1:0", * temperature: 0, * maxTokens: undefined, From abb7bb8ecc891a7548bd2bfcc1f354f5ad95065c Mon Sep 17 00:00:00 2001 From: jacoblee93 Date: Mon, 23 Sep 2024 19:20:10 -0700 Subject: [PATCH 4/6] Fixes --- .../src/chat_models/bedrock/web.ts | 57 +++++++++---------- .../src/chat_models/tests/chatbedrock.test.ts | 29 ++++++++++ .../src/utils/bedrock/index.ts | 4 +- 3 files changed, 60 insertions(+), 30 deletions(-) diff --git a/libs/langchain-community/src/chat_models/bedrock/web.ts b/libs/langchain-community/src/chat_models/bedrock/web.ts index 4d17a3dc25b5..0ea7d4880f12 100644 --- a/libs/langchain-community/src/chat_models/bedrock/web.ts +++ b/libs/langchain-community/src/chat_models/bedrock/web.ts @@ -495,10 +495,7 @@ export class BedrockChat region: string; - credentials?: CredentialType; - awsAccessKeyID?: string; - awsSecretAccessKey?: string; - awsSessionToken?: string; + credentials: CredentialType; temperature?: number | undefined = undefined; @@ -543,6 +540,7 @@ export class BedrockChat return { "credentials.accessKeyId": "AWS_ACCESS_KEY_ID", "credentials.secretAccessKey": "AWS_SECRET_ACCESS_KEY", + "credentials.sessionToken": "AWS_SECRET_ACCESS_KEY", awsAccessKeyId: "AWS_ACCESS_KEY_ID", awsSecretAccessKey: "AWS_SECRET_ACCESS_KEY", awsSessionToken: "AWS_SESSION_TOKEN", @@ -568,7 +566,32 @@ export class BedrockChat } constructor(fields?: BedrockChatFields) { - super(fields ?? {}); + const awsAccessKeyId = + fields?.awsAccessKeyId ?? getEnvironmentVariable("AWS_ACCESS_KEY_ID"); + const awsSecretAccessKey = + fields?.awsSecretAccessKey ?? + getEnvironmentVariable("AWS_SECRET_ACCESS_KEY"); + const awsSessionToken = + fields?.awsSessionToken ?? getEnvironmentVariable("AWS_SESSION_TOKEN"); + + let credentials = fields?.credentials; + if (credentials === undefined) { + if (awsAccessKeyId === undefined || awsSecretAccessKey === undefined) { + throw new Error( + "Please set your AWS credentials in the 'credentials' field or set env vars AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, and optionally AWS_SESSION_TOKEN." + ); + } + credentials = { + accessKeyId: awsAccessKeyId, + secretAccessKey: awsSecretAccessKey, + sessionToken: awsSessionToken, + }; + } + + // eslint-disable-next-line no-param-reassign + fields = { ...fields, awsAccessKeyId, awsSecretAccessKey, awsSessionToken }; + + super(fields); this.model = fields?.model ?? this.model; this.modelProvider = getModelProvider(this.model); @@ -587,30 +610,6 @@ export class BedrockChat } this.region = region; - this.awsAccessKeyID = - fields?.awsAccessKeyID || getEnvironmentVariable("AWS_ACCESS_KEY_ID"); - this.awsSecretAccessKey = - fields?.awsSecretAccessKey || - getEnvironmentVariable("AWS_SECRET_ACCESS_KEY"); - this.awsSessionToken = - fields?.awsSessionToken || getEnvironmentVariable("AWS_SESSION_TOKEN"); - const credentials = fields?.credentials ?? { - ...(this.awsAccessKeyID !== undefined && { - accessKeyID: this.awsAccessKeyID, - }), - ...(this.awsSecretAccessKey !== undefined && { - secretAccessKey: this.awsSecretAccessKey, - }), - ...(this.awsSessionToken !== undefined && { - sessionToken: this.awsSessionToken, - }), - }; - - if (!credentials) { - throw new Error( - "Please set the AWS credentials in the 'credentials' field or set env vars AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, or AWS_SESSION_TOKEN." - ); - } this.credentials = credentials; this.temperature = fields?.temperature ?? this.temperature; diff --git a/libs/langchain-community/src/chat_models/tests/chatbedrock.test.ts b/libs/langchain-community/src/chat_models/tests/chatbedrock.test.ts index 4caba4ee3a5c..f0a516a2313e 100644 --- a/libs/langchain-community/src/chat_models/tests/chatbedrock.test.ts +++ b/libs/langchain-community/src/chat_models/tests/chatbedrock.test.ts @@ -26,3 +26,32 @@ test("Test Bedrock identifying params", async () => { model, }); }); + +test("Test Bedrock serialization", async () => { + const bedrock = new BedrockChat({ + region: "us-west-2", + model: "anthropic.claude-3-sonnet-20240229-v1:0", + credentials: { + accessKeyId: "unused", + secretAccessKey: "unused", + sessionToken: "unused", + }, + }); + + expect(JSON.stringify(bedrock)).toEqual( + `{"lc":1,"type":"constructor","id":["langchain","chat_models","bedrock","BedrockChat"],"kwargs":{"region_name":"us-west-2","model_id":"anthropic.claude-3-sonnet-20240229-v1:0","credentials":{"accessKeyId":{"lc":1,"type":"secret","id":["AWS_ACCESS_KEY_ID"]},"secretAccessKey":{"lc":1,"type":"secret","id":["AWS_SECRET_ACCESS_KEY"]},"sessionToken":{"lc":1,"type":"secret","id":["AWS_SECRET_ACCESS_KEY"]}},"aws_access_key_id":{"lc":1,"type":"secret","id":["AWS_ACCESS_KEY_ID"]},"aws_secret_access_key":{"lc":1,"type":"secret","id":["AWS_SECRET_ACCESS_KEY"]}}}` + ); +}); + +test("Test Bedrock serialization with no parameters", async () => { + process.env.AWS_ACCESS_KEY_ID = "foo"; + process.env.AWS_SECRET_ACCESS_KEY = "bar"; + const bedrock = new BedrockChat({ + region: "us-west-2", + model: "anthropic.claude-3-sonnet-20240229-v1:0", + }); + + expect(JSON.stringify(bedrock)).toEqual( + `{"lc":1,"type":"constructor","id":["langchain","chat_models","bedrock","BedrockChat"],"kwargs":{"region_name":"us-west-2","model_id":"anthropic.claude-3-sonnet-20240229-v1:0","aws_access_key_id":{"lc":1,"type":"secret","id":["AWS_ACCESS_KEY_ID"]},"aws_secret_access_key":{"lc":1,"type":"secret","id":["AWS_SECRET_ACCESS_KEY"]},"credentials":{"accessKeyId":{"lc":1,"type":"secret","id":["AWS_ACCESS_KEY_ID"]},"secretAccessKey":{"lc":1,"type":"secret","id":["AWS_SECRET_ACCESS_KEY"]}}}}` + ); +}); diff --git a/libs/langchain-community/src/utils/bedrock/index.ts b/libs/langchain-community/src/utils/bedrock/index.ts index 1fdbfbd328fc..9b3203e8ce76 100644 --- a/libs/langchain-community/src/utils/bedrock/index.ts +++ b/libs/langchain-community/src/utils/bedrock/index.ts @@ -169,8 +169,10 @@ export interface BaseBedrockInput { streamProcessingMode: "SYNCHRONOUS" | "ASYNCHRONOUS"; }; - awsAccessKeyID?: string; + awsAccessKeyId?: string; + awsSecretAccessKey?: string; + awsSessionToken?: string; } From 239968330916c1dccc7e1721df02cc3927316cdf Mon Sep 17 00:00:00 2001 From: jacoblee93 Date: Mon, 23 Sep 2024 19:23:09 -0700 Subject: [PATCH 5/6] Readd explicit credentials example --- .../src/chat_models/bedrock/index.ts | 10 ++++++++++ .../src/chat_models/bedrock/web.ts | 12 +++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/libs/langchain-community/src/chat_models/bedrock/index.ts b/libs/langchain-community/src/chat_models/bedrock/index.ts index 11c7be94d85c..9cf533a4c3f5 100644 --- a/libs/langchain-community/src/chat_models/bedrock/index.ts +++ b/libs/langchain-community/src/chat_models/bedrock/index.ts @@ -65,6 +65,16 @@ export interface BedrockChatFields * maxTokens: undefined, * // other params... * }); + * + * // You can also pass credentials in explicitly: + * const llmWithCredentials = new BedrockChat({ + * region: process.env.BEDROCK_AWS_REGION, + * model: "anthropic.claude-3-5-sonnet-20240620-v1:0", + * credentials: { + * secretAccessKey: process.env.BEDROCK_AWS_SECRET_ACCESS_KEY!, + * accessKeyId: process.env.BEDROCK_AWS_ACCESS_KEY_ID!, + * }, + * }); * ``` * * diff --git a/libs/langchain-community/src/chat_models/bedrock/web.ts b/libs/langchain-community/src/chat_models/bedrock/web.ts index 0ea7d4880f12..8e227a81ec2d 100644 --- a/libs/langchain-community/src/chat_models/bedrock/web.ts +++ b/libs/langchain-community/src/chat_models/bedrock/web.ts @@ -217,7 +217,7 @@ export interface BedrockChatFields * Instantiate * * ```typescript - * import { BedrockChat } from '@langchain/community/chat_models/bedrock'; + * import { BedrockChat } from '@langchain/community/chat_models/bedrock/web'; * * const llm = new BedrockChat({ * region: process.env.AWS_REGION, @@ -227,6 +227,16 @@ export interface BedrockChatFields * maxTokens: undefined, * // other params... * }); + * + * // You can also pass credentials in explicitly: + * const llmWithCredentials = new BedrockChat({ + * region: process.env.BEDROCK_AWS_REGION, + * model: "anthropic.claude-3-5-sonnet-20240620-v1:0", + * credentials: { + * secretAccessKey: process.env.BEDROCK_AWS_SECRET_ACCESS_KEY!, + * accessKeyId: process.env.BEDROCK_AWS_ACCESS_KEY_ID!, + * }, + * }); * ``` * * From b507fbc1447ccb00ba1038fa80b202df7a40ddbc Mon Sep 17 00:00:00 2001 From: jacoblee93 Date: Tue, 24 Sep 2024 18:29:54 -0700 Subject: [PATCH 6/6] Fix test --- .../src/chat_models/tests/chatbedrock.test.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libs/langchain-community/src/chat_models/tests/chatbedrock.test.ts b/libs/langchain-community/src/chat_models/tests/chatbedrock.test.ts index f0a516a2313e..666daca6fc68 100644 --- a/libs/langchain-community/src/chat_models/tests/chatbedrock.test.ts +++ b/libs/langchain-community/src/chat_models/tests/chatbedrock.test.ts @@ -28,6 +28,8 @@ test("Test Bedrock identifying params", async () => { }); test("Test Bedrock serialization", async () => { + delete process.env.AWS_ACCESS_KEY_ID; + delete process.env.AWS_SECRET_ACCESS_KEY; const bedrock = new BedrockChat({ region: "us-west-2", model: "anthropic.claude-3-sonnet-20240229-v1:0", @@ -39,11 +41,11 @@ test("Test Bedrock serialization", async () => { }); expect(JSON.stringify(bedrock)).toEqual( - `{"lc":1,"type":"constructor","id":["langchain","chat_models","bedrock","BedrockChat"],"kwargs":{"region_name":"us-west-2","model_id":"anthropic.claude-3-sonnet-20240229-v1:0","credentials":{"accessKeyId":{"lc":1,"type":"secret","id":["AWS_ACCESS_KEY_ID"]},"secretAccessKey":{"lc":1,"type":"secret","id":["AWS_SECRET_ACCESS_KEY"]},"sessionToken":{"lc":1,"type":"secret","id":["AWS_SECRET_ACCESS_KEY"]}},"aws_access_key_id":{"lc":1,"type":"secret","id":["AWS_ACCESS_KEY_ID"]},"aws_secret_access_key":{"lc":1,"type":"secret","id":["AWS_SECRET_ACCESS_KEY"]}}}` + `{"lc":1,"type":"constructor","id":["langchain","chat_models","bedrock","BedrockChat"],"kwargs":{"region_name":"us-west-2","model_id":"anthropic.claude-3-sonnet-20240229-v1:0","credentials":{"accessKeyId":{"lc":1,"type":"secret","id":["AWS_ACCESS_KEY_ID"]},"secretAccessKey":{"lc":1,"type":"secret","id":["AWS_SECRET_ACCESS_KEY"]},"sessionToken":{"lc":1,"type":"secret","id":["AWS_SECRET_ACCESS_KEY"]}}}}` ); }); -test("Test Bedrock serialization with no parameters", async () => { +test("Test Bedrock serialization from environment variables", async () => { process.env.AWS_ACCESS_KEY_ID = "foo"; process.env.AWS_SECRET_ACCESS_KEY = "bar"; const bedrock = new BedrockChat({