Skip to content

Commit 85e1e27

Browse files
feat(piece): add aws bedrock (activepieces#11223)
1 parent 528069a commit 85e1e27

File tree

14 files changed

+1288
-0
lines changed

14 files changed

+1288
-0
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"extends": [
3+
"../../../../.eslintrc.base.json"
4+
],
5+
"ignorePatterns": [
6+
"!**/*"
7+
],
8+
"overrides": [
9+
{
10+
"files": [
11+
"*.ts",
12+
"*.tsx",
13+
"*.js",
14+
"*.jsx"
15+
],
16+
"rules": {}
17+
},
18+
{
19+
"files": [
20+
"*.ts",
21+
"*.tsx"
22+
],
23+
"rules": {}
24+
},
25+
{
26+
"files": [
27+
"*.js",
28+
"*.jsx"
29+
],
30+
"rules": {}
31+
}
32+
]
33+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# pieces-aws-bedrock
2+
3+
This library was generated with [Nx](https://nx.dev).
4+
5+
## Building
6+
7+
Run `nx build pieces-aws-bedrock` to build the library.

packages/pieces/community/aws-bedrock/bun.lock

Lines changed: 216 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"name": "@activepieces/piece-aws-bedrock",
3+
"version": "0.0.1",
4+
"type": "commonjs",
5+
"main": "./src/index.js",
6+
"types": "./src/index.d.ts",
7+
"dependencies": {
8+
"@aws-sdk/client-bedrock": "^3.987.0",
9+
"@aws-sdk/client-bedrock-runtime": "^3.987.0",
10+
"tslib": "^2.3.0"
11+
}
12+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
{
2+
"name": "pieces-aws-bedrock",
3+
"$schema": "../../../../node_modules/nx/schemas/project-schema.json",
4+
"sourceRoot": "packages/pieces/community/aws-bedrock/src",
5+
"projectType": "library",
6+
"release": {
7+
"version": {
8+
"manifestRootsToUpdate": [
9+
"dist/{projectRoot}"
10+
],
11+
"currentVersionResolver": "git-tag",
12+
"fallbackCurrentVersionResolver": "disk"
13+
}
14+
},
15+
"tags": [],
16+
"targets": {
17+
"build": {
18+
"executor": "@nx/js:tsc",
19+
"outputs": [
20+
"{options.outputPath}"
21+
],
22+
"options": {
23+
"outputPath": "dist/packages/pieces/community/aws-bedrock",
24+
"tsConfig": "packages/pieces/community/aws-bedrock/tsconfig.lib.json",
25+
"packageJson": "packages/pieces/community/aws-bedrock/package.json",
26+
"main": "packages/pieces/community/aws-bedrock/src/index.ts",
27+
"assets": [
28+
"packages/pieces/community/aws-bedrock/*.md",
29+
{
30+
"input": "packages/pieces/community/aws-bedrock/src/i18n",
31+
"output": "./src/i18n",
32+
"glob": "**/!(i18n.json)"
33+
}
34+
],
35+
"buildableProjectDepsInPackageJsonType": "dependencies",
36+
"updateBuildableProjectDepsInPackageJson": true,
37+
"clean": false
38+
},
39+
"dependsOn": [
40+
"prebuild",
41+
"^build"
42+
]
43+
},
44+
"nx-release-publish": {
45+
"options": {
46+
"packageRoot": "dist/{projectRoot}"
47+
}
48+
},
49+
"prebuild": {
50+
"dependsOn": [
51+
"^build"
52+
],
53+
"executor": "nx:run-commands",
54+
"options": {
55+
"cwd": "packages/pieces/community/aws-bedrock",
56+
"command": "bun install --no-save --silent"
57+
}
58+
},
59+
"lint": {
60+
"executor": "@nx/eslint:lint",
61+
"outputs": [
62+
"{options.outputFile}"
63+
]
64+
}
65+
}
66+
}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import {
2+
PieceAuth,
3+
Property,
4+
createPiece,
5+
} from '@activepieces/pieces-framework';
6+
import { PieceCategory } from '@activepieces/shared';
7+
import { ListFoundationModelsCommand } from '@aws-sdk/client-bedrock';
8+
import { sendPrompt } from './lib/actions/send-prompt';
9+
import { generateContentFromImage } from './lib/actions/generate-content-from-image';
10+
import { generateImage } from './lib/actions/generate-image';
11+
import { generateEmbeddings } from './lib/actions/generate-embeddings';
12+
import { createBedrockClient } from './lib/common';
13+
14+
export const awsBedrockAuth = PieceAuth.CustomAuth({
15+
description: 'AWS Bedrock authentication using Access Key and Secret Key.',
16+
props: {
17+
accessKeyId: Property.ShortText({
18+
displayName: 'Access Key ID',
19+
required: true,
20+
}),
21+
secretAccessKey: PieceAuth.SecretText({
22+
displayName: 'Secret Access Key',
23+
required: true,
24+
}),
25+
region: Property.StaticDropdown({
26+
displayName: 'Region',
27+
required: true,
28+
options: {
29+
options: [
30+
{ label: 'US East (N. Virginia) [us-east-1]', value: 'us-east-1' },
31+
{ label: 'US East (Ohio) [us-east-2]', value: 'us-east-2' },
32+
{ label: 'US West (Oregon) [us-west-2]', value: 'us-west-2' },
33+
{
34+
label: 'Asia Pacific (Hyderabad) [ap-south-2]',
35+
value: 'ap-south-2',
36+
},
37+
{
38+
label: 'Asia Pacific (Mumbai) [ap-south-1]',
39+
value: 'ap-south-1',
40+
},
41+
{
42+
label: 'Asia Pacific (Osaka) [ap-northeast-3]',
43+
value: 'ap-northeast-3',
44+
},
45+
{
46+
label: 'Asia Pacific (Seoul) [ap-northeast-2]',
47+
value: 'ap-northeast-2',
48+
},
49+
{
50+
label: 'Asia Pacific (Singapore) [ap-southeast-1]',
51+
value: 'ap-southeast-1',
52+
},
53+
{
54+
label: 'Asia Pacific (Sydney) [ap-southeast-2]',
55+
value: 'ap-southeast-2',
56+
},
57+
{
58+
label: 'Asia Pacific (Tokyo) [ap-northeast-1]',
59+
value: 'ap-northeast-1',
60+
},
61+
{
62+
label: 'Canada (Central) [ca-central-1]',
63+
value: 'ca-central-1',
64+
},
65+
{
66+
label: 'Europe (Frankfurt) [eu-central-1]',
67+
value: 'eu-central-1',
68+
},
69+
{ label: 'Europe (Ireland) [eu-west-1]', value: 'eu-west-1' },
70+
{ label: 'Europe (London) [eu-west-2]', value: 'eu-west-2' },
71+
{ label: 'Europe (Milan) [eu-south-1]', value: 'eu-south-1' },
72+
{ label: 'Europe (Paris) [eu-west-3]', value: 'eu-west-3' },
73+
{ label: 'Europe (Spain) [eu-south-2]', value: 'eu-south-2' },
74+
{
75+
label: 'Europe (Stockholm) [eu-north-1]',
76+
value: 'eu-north-1',
77+
},
78+
{
79+
label: 'Europe (Zurich) [eu-central-2]',
80+
value: 'eu-central-2',
81+
},
82+
{
83+
label: 'South America (São Paulo) [sa-east-1]',
84+
value: 'sa-east-1',
85+
},
86+
],
87+
},
88+
}),
89+
},
90+
validate: async ({ auth }) => {
91+
try {
92+
const client = createBedrockClient(auth);
93+
await client.send(new ListFoundationModelsCommand({}));
94+
return { valid: true };
95+
} catch (e) {
96+
return {
97+
valid: false,
98+
error: (e as Error)?.message,
99+
};
100+
}
101+
},
102+
required: true,
103+
});
104+
105+
export const awsBedrock = createPiece({
106+
displayName: 'AWS Bedrock',
107+
description: 'Build generative AI applications with foundation models',
108+
auth: awsBedrockAuth,
109+
minimumSupportedRelease: '0.36.1',
110+
logoUrl: 'https://cdn.activepieces.com/pieces/aws-bedrock.png',
111+
categories: [PieceCategory.ARTIFICIAL_INTELLIGENCE],
112+
authors: ["onyedikachi-david"],
113+
actions: [sendPrompt, generateContentFromImage, generateImage, generateEmbeddings],
114+
triggers: [],
115+
});
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
import { createAction, Property } from '@activepieces/pieces-framework';
2+
import {
3+
ConverseCommand,
4+
ConversationRole,
5+
ImageFormat,
6+
} from '@aws-sdk/client-bedrock-runtime';
7+
import { ModelModality } from '@aws-sdk/client-bedrock';
8+
import { awsBedrockAuth } from '../../index';
9+
import {
10+
createBedrockRuntimeClient,
11+
getBedrockModelOptions,
12+
formatBedrockError,
13+
extractConverseTextResponse,
14+
} from '../common';
15+
16+
const EXTENSION_TO_FORMAT: Record<string, ImageFormat> = {
17+
png: ImageFormat.PNG,
18+
jpg: ImageFormat.JPEG,
19+
jpeg: ImageFormat.JPEG,
20+
gif: ImageFormat.GIF,
21+
webp: ImageFormat.WEBP,
22+
};
23+
24+
export const generateContentFromImage = createAction({
25+
auth: awsBedrockAuth,
26+
name: 'generate_content_from_image',
27+
displayName: 'Generate Content from Image',
28+
description: 'Ask a Bedrock model a question about an image.',
29+
props: {
30+
model: Property.Dropdown({
31+
displayName: 'Model',
32+
required: true,
33+
auth: awsBedrockAuth,
34+
description: 'The foundation model to use. Must support image input.',
35+
refreshers: [],
36+
options: async ({ auth }) => {
37+
if (!auth) {
38+
return {
39+
disabled: true,
40+
placeholder: 'Connect your AWS account first',
41+
options: [],
42+
};
43+
}
44+
return getBedrockModelOptions(auth.props, {
45+
useInferenceProfiles: true,
46+
inputModality: ModelModality.IMAGE,
47+
});
48+
},
49+
}),
50+
image: Property.File({
51+
displayName: 'Image',
52+
required: true,
53+
description: 'The image to analyze (PNG, JPEG, GIF, or WebP).',
54+
}),
55+
prompt: Property.LongText({
56+
displayName: 'Prompt',
57+
required: true,
58+
description: 'What do you want the model to tell you about the image?',
59+
}),
60+
systemPrompt: Property.LongText({
61+
displayName: 'System Prompt',
62+
required: false,
63+
description: 'Instructions that guide the model behavior.',
64+
}),
65+
temperature: Property.Number({
66+
displayName: 'Temperature',
67+
required: false,
68+
description:
69+
'Controls randomness. Lower values produce more deterministic output.',
70+
defaultValue: 0.7,
71+
}),
72+
maxTokens: Property.Number({
73+
displayName: 'Maximum Tokens',
74+
required: false,
75+
description: 'The maximum number of tokens to generate.',
76+
defaultValue: 2048,
77+
}),
78+
},
79+
async run({ auth, propsValue }) {
80+
const client = createBedrockRuntimeClient(auth.props);
81+
const { model, image, prompt, systemPrompt, temperature, maxTokens } =
82+
propsValue;
83+
84+
const ext = (image.extension ?? 'png').toLowerCase();
85+
const format = EXTENSION_TO_FORMAT[ext];
86+
if (!format) {
87+
throw new Error(
88+
`Unsupported image format "${ext}". Supported: png, jpeg, gif, webp.`
89+
);
90+
}
91+
92+
const imageBytes = Buffer.from(image.base64, 'base64');
93+
94+
try {
95+
const response = await client.send(
96+
new ConverseCommand({
97+
modelId: model,
98+
messages: [
99+
{
100+
role: ConversationRole.USER,
101+
content: [
102+
{
103+
image: {
104+
format,
105+
source: { bytes: imageBytes },
106+
},
107+
},
108+
{ text: prompt },
109+
],
110+
},
111+
],
112+
...(systemPrompt ? { system: [{ text: systemPrompt }] } : {}),
113+
inferenceConfig: {
114+
temperature: temperature ?? undefined,
115+
maxTokens: maxTokens ?? undefined,
116+
},
117+
})
118+
);
119+
120+
return extractConverseTextResponse(response);
121+
} catch (error) {
122+
throw new Error(formatBedrockError(error));
123+
}
124+
},
125+
});

0 commit comments

Comments
 (0)