Skip to content

Commit 0e2cba0

Browse files
authored
Merge pull request #1034 from FlowiseAI/feature/BedrockEmbeddings
Feature/AWSBedrock embeddings
2 parents b96274b + 536ed07 commit 0e2cba0

File tree

5 files changed

+167
-33
lines changed

5 files changed

+167
-33
lines changed

packages/components/nodes/chatmodels/AWSBedrock/AWSChatBedrock.ts

+6-17
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class AWSChatBedrock_ChatModels implements INode {
3131
this.type = 'AWSChatBedrock'
3232
this.icon = 'awsBedrock.png'
3333
this.category = 'Chat Models'
34-
this.description = 'Wrapper around AWS Bedrock large language models'
34+
this.description = 'Wrapper around AWS Bedrock large language models that use the Chat endpoint'
3535
this.baseClasses = [this.type, ...getBaseClasses(ChatBedrock)]
3636
this.credential = {
3737
label: 'AWS Credential',
@@ -88,27 +88,18 @@ class AWSChatBedrock_ChatModels implements INode {
8888
{ label: 'us-west-1', name: 'us-west-1' },
8989
{ label: 'us-west-2', name: 'us-west-2' }
9090
],
91-
default: 'us-east-1',
92-
optional: false
91+
default: 'us-east-1'
9392
},
9493
{
9594
label: 'Model Name',
9695
name: 'model',
9796
type: 'options',
9897
options: [
99-
{ label: 'amazon.titan-tg1-large', name: 'amazon.titan-tg1-large' },
100-
{ label: 'amazon.titan-e1t-medium', name: 'amazon.titan-e1t-medium' },
101-
{ label: 'stability.stable-diffusion-xl', name: 'stability.stable-diffusion-xl' },
102-
{ label: 'ai21.j2-grande-instruct', name: 'ai21.j2-grande-instruct' },
103-
{ label: 'ai21.j2-jumbo-instruct', name: 'ai21.j2-jumbo-instruct' },
104-
{ label: 'ai21.j2-mid', name: 'ai21.j2-mid' },
105-
{ label: 'ai21.j2-ultra', name: 'ai21.j2-ultra' },
10698
{ label: 'anthropic.claude-instant-v1', name: 'anthropic.claude-instant-v1' },
10799
{ label: 'anthropic.claude-v1', name: 'anthropic.claude-v1' },
108100
{ label: 'anthropic.claude-v2', name: 'anthropic.claude-v2' }
109101
],
110-
default: 'anthropic.claude-v2',
111-
optional: false
102+
default: 'anthropic.claude-v2'
112103
},
113104
{
114105
label: 'Temperature',
@@ -117,18 +108,16 @@ class AWSChatBedrock_ChatModels implements INode {
117108
step: 0.1,
118109
description: 'Temperature parameter may not apply to certain model. Please check available model parameters',
119110
optional: true,
120-
default: 0.7,
121-
additionalParams: false
111+
default: 0.7
122112
},
123113
{
124114
label: 'Max Tokens to Sample',
125115
name: 'max_tokens_to_sample',
126116
type: 'number',
127117
step: 10,
128118
description: 'Max Tokens parameter may not apply to certain model. Please check available model parameters',
129-
optional: false,
130-
default: 200,
131-
additionalParams: false
119+
optional: true,
120+
default: 200
132121
}
133122
]
134123
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
2+
import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
3+
import { BedrockEmbeddings, BedrockEmbeddingsParams } from 'langchain/embeddings/bedrock'
4+
import { BedrockRuntimeClient, InvokeModelCommand } from '@aws-sdk/client-bedrock-runtime'
5+
6+
class AWSBedrockEmbedding_Embeddings implements INode {
7+
label: string
8+
name: string
9+
version: number
10+
type: string
11+
icon: string
12+
category: string
13+
description: string
14+
baseClasses: string[]
15+
credential: INodeParams
16+
inputs: INodeParams[]
17+
18+
constructor() {
19+
this.label = 'AWS Bedrock Embeddings'
20+
this.name = 'AWSBedrockEmbeddings'
21+
this.version = 1.0
22+
this.type = 'AWSBedrockEmbeddings'
23+
this.icon = 'awsBedrock.png'
24+
this.category = 'Embeddings'
25+
this.description = 'AWSBedrock embedding models to generate embeddings for a given text'
26+
this.baseClasses = [this.type, ...getBaseClasses(BedrockEmbeddings)]
27+
this.credential = {
28+
label: 'AWS Credential',
29+
name: 'credential',
30+
type: 'credential',
31+
credentialNames: ['awsApi'],
32+
optional: true
33+
}
34+
this.inputs = [
35+
{
36+
label: 'Region',
37+
name: 'region',
38+
type: 'options',
39+
options: [
40+
{ label: 'af-south-1', name: 'af-south-1' },
41+
{ label: 'ap-east-1', name: 'ap-east-1' },
42+
{ label: 'ap-northeast-1', name: 'ap-northeast-1' },
43+
{ label: 'ap-northeast-2', name: 'ap-northeast-2' },
44+
{ label: 'ap-northeast-3', name: 'ap-northeast-3' },
45+
{ label: 'ap-south-1', name: 'ap-south-1' },
46+
{ label: 'ap-south-2', name: 'ap-south-2' },
47+
{ label: 'ap-southeast-1', name: 'ap-southeast-1' },
48+
{ label: 'ap-southeast-2', name: 'ap-southeast-2' },
49+
{ label: 'ap-southeast-3', name: 'ap-southeast-3' },
50+
{ label: 'ap-southeast-4', name: 'ap-southeast-4' },
51+
{ label: 'ap-southeast-5', name: 'ap-southeast-5' },
52+
{ label: 'ap-southeast-6', name: 'ap-southeast-6' },
53+
{ label: 'ca-central-1', name: 'ca-central-1' },
54+
{ label: 'ca-west-1', name: 'ca-west-1' },
55+
{ label: 'cn-north-1', name: 'cn-north-1' },
56+
{ label: 'cn-northwest-1', name: 'cn-northwest-1' },
57+
{ label: 'eu-central-1', name: 'eu-central-1' },
58+
{ label: 'eu-central-2', name: 'eu-central-2' },
59+
{ label: 'eu-north-1', name: 'eu-north-1' },
60+
{ label: 'eu-south-1', name: 'eu-south-1' },
61+
{ label: 'eu-south-2', name: 'eu-south-2' },
62+
{ label: 'eu-west-1', name: 'eu-west-1' },
63+
{ label: 'eu-west-2', name: 'eu-west-2' },
64+
{ label: 'eu-west-3', name: 'eu-west-3' },
65+
{ label: 'il-central-1', name: 'il-central-1' },
66+
{ label: 'me-central-1', name: 'me-central-1' },
67+
{ label: 'me-south-1', name: 'me-south-1' },
68+
{ label: 'sa-east-1', name: 'sa-east-1' },
69+
{ label: 'us-east-1', name: 'us-east-1' },
70+
{ label: 'us-east-2', name: 'us-east-2' },
71+
{ label: 'us-gov-east-1', name: 'us-gov-east-1' },
72+
{ label: 'us-gov-west-1', name: 'us-gov-west-1' },
73+
{ label: 'us-west-1', name: 'us-west-1' },
74+
{ label: 'us-west-2', name: 'us-west-2' }
75+
],
76+
default: 'us-east-1'
77+
},
78+
{
79+
label: 'Model Name',
80+
name: 'model',
81+
type: 'options',
82+
options: [{ label: 'amazon.titan-embed-text-v1', name: 'amazon.titan-embed-text-v1' }],
83+
default: 'amazon.titan-embed-text-v1'
84+
}
85+
]
86+
}
87+
88+
async init(nodeData: INodeData, _: string, options: ICommonObject): Promise<any> {
89+
const iRegion = nodeData.inputs?.region as string
90+
const iModel = nodeData.inputs?.model as string
91+
92+
const obj: BedrockEmbeddingsParams = {
93+
model: iModel,
94+
region: iRegion
95+
}
96+
97+
const credentialData = await getCredentialData(nodeData.credential ?? '', options)
98+
if (credentialData && Object.keys(credentialData).length !== 0) {
99+
const credentialApiKey = getCredentialParam('awsKey', credentialData, nodeData)
100+
const credentialApiSecret = getCredentialParam('awsSecret', credentialData, nodeData)
101+
const credentialApiSession = getCredentialParam('awsSession', credentialData, nodeData)
102+
103+
obj.credentials = {
104+
accessKeyId: credentialApiKey,
105+
secretAccessKey: credentialApiSecret,
106+
sessionToken: credentialApiSession
107+
}
108+
}
109+
110+
const client = new BedrockRuntimeClient({
111+
region: obj.region,
112+
credentials: obj.credentials
113+
})
114+
115+
const model = new BedrockEmbeddings(obj)
116+
117+
// Avoid Illegal Invocation
118+
model.embedQuery = async (document: string): Promise<number[]> => {
119+
return await embedText(document, client, iModel)
120+
}
121+
122+
model.embedDocuments = async (documents: string[]): Promise<number[][]> => {
123+
return Promise.all(documents.map((document) => embedText(document, client, iModel)))
124+
}
125+
return model
126+
}
127+
}
128+
129+
const embedText = async (text: string, client: BedrockRuntimeClient, model: string): Promise<number[]> => {
130+
// replace newlines, which can negatively affect performance.
131+
const cleanedText = text.replace(/\n/g, ' ')
132+
133+
const res = await client.send(
134+
new InvokeModelCommand({
135+
modelId: model,
136+
body: JSON.stringify({
137+
inputText: cleanedText
138+
}),
139+
contentType: 'application/json',
140+
accept: 'application/json'
141+
})
142+
)
143+
144+
try {
145+
const body = new TextDecoder().decode(res.body)
146+
return JSON.parse(body).embedding
147+
} catch (e) {
148+
throw new Error('An invalid response was returned by Bedrock.')
149+
}
150+
}
151+
152+
module.exports = { nodeClass: AWSBedrockEmbedding_Embeddings }
Loading

packages/components/nodes/llms/AWSBedrock/AWSBedrock.ts

+7-15
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,7 @@ class AWSBedrock_LLMs implements INode {
8888
{ label: 'us-west-1', name: 'us-west-1' },
8989
{ label: 'us-west-2', name: 'us-west-2' }
9090
],
91-
default: 'us-east-1',
92-
optional: false
91+
default: 'us-east-1'
9392
},
9493
{
9594
label: 'Model Name',
@@ -98,17 +97,12 @@ class AWSBedrock_LLMs implements INode {
9897
options: [
9998
{ label: 'amazon.titan-tg1-large', name: 'amazon.titan-tg1-large' },
10099
{ label: 'amazon.titan-e1t-medium', name: 'amazon.titan-e1t-medium' },
101-
{ label: 'stability.stable-diffusion-xl', name: 'stability.stable-diffusion-xl' },
100+
{ label: 'cohere.command-text-v14', name: 'cohere.command-text-v14' },
102101
{ label: 'ai21.j2-grande-instruct', name: 'ai21.j2-grande-instruct' },
103102
{ label: 'ai21.j2-jumbo-instruct', name: 'ai21.j2-jumbo-instruct' },
104103
{ label: 'ai21.j2-mid', name: 'ai21.j2-mid' },
105-
{ label: 'ai21.j2-ultra', name: 'ai21.j2-ultra' },
106-
{ label: 'anthropic.claude-instant-v1', name: 'anthropic.claude-instant-v1' },
107-
{ label: 'anthropic.claude-v1', name: 'anthropic.claude-v1' },
108-
{ label: 'anthropic.claude-v2', name: 'anthropic.claude-v2' }
109-
],
110-
default: 'anthropic.claude-v2',
111-
optional: false
104+
{ label: 'ai21.j2-ultra', name: 'ai21.j2-ultra' }
105+
]
112106
},
113107
{
114108
label: 'Temperature',
@@ -117,18 +111,16 @@ class AWSBedrock_LLMs implements INode {
117111
step: 0.1,
118112
description: 'Temperature parameter may not apply to certain model. Please check available model parameters',
119113
optional: true,
120-
default: 0.7,
121-
additionalParams: false
114+
default: 0.7
122115
},
123116
{
124117
label: 'Max Tokens to Sample',
125118
name: 'max_tokens_to_sample',
126119
type: 'number',
127120
step: 10,
128121
description: 'Max Tokens parameter may not apply to certain model. Please check available model parameters',
129-
optional: false,
130-
default: 200,
131-
additionalParams: false
122+
optional: true,
123+
default: 200
132124
}
133125
]
134126
}

packages/components/package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
},
1717
"license": "SEE LICENSE IN LICENSE.md",
1818
"dependencies": {
19+
"@aws-sdk/client-bedrock-runtime": "3.422.0",
1920
"@aws-sdk/client-dynamodb": "^3.360.0",
2021
"@dqbd/tiktoken": "^1.0.7",
2122
"@getzep/zep-js": "^0.6.3",
@@ -45,7 +46,7 @@
4546
"graphql": "^16.6.0",
4647
"html-to-text": "^9.0.5",
4748
"ioredis": "^5.3.2",
48-
"langchain": "^0.0.157",
49+
"langchain": "^0.0.165",
4950
"langfuse-langchain": "^1.0.14-alpha.0",
5051
"langsmith": "^0.0.32",
5152
"linkifyjs": "^4.1.1",

0 commit comments

Comments
 (0)