From 694f7690b50c1fe4758515be313977359326cd47 Mon Sep 17 00:00:00 2001 From: krokoko Date: Tue, 12 Nov 2024 13:57:23 -0600 Subject: [PATCH 01/22] chore(update): update to cdk 2.166.0 --- .projen/deps.json | 4 +-- .projenrc.ts | 2 +- CHANGELOG.md | 4 +++ DEVELOPER_GUIDE.md | 2 +- apidocs/interfaces/DockerLambdaCustomProps.md | 2 +- .../bedrock/classes/PromptVariant.md | 4 +-- package.json | 6 ++-- src/cdk-lib/bedrock/README.md | 6 ++-- src/cdk-lib/bedrock/prompts/prompt.ts | 2 +- src/common/props/DockerLambdaCustomProps.ts | 2 +- test/cdk-lib/bedrock/prompts.test.ts | 3 -- yarn.lock | 34 +++++++++---------- 12 files changed, 36 insertions(+), 35 deletions(-) diff --git a/.projen/deps.json b/.projen/deps.json index cb07eb71..f367a4fe 100644 --- a/.projen/deps.json +++ b/.projen/deps.json @@ -6,7 +6,7 @@ }, { "name": "@aws-cdk/integ-tests-alpha", - "version": "2.162.1-alpha.0", + "version": "2.166.0-alpha.0", "type": "build" }, { @@ -137,7 +137,7 @@ }, { "name": "aws-cdk-lib", - "version": "^2.162.1", + "version": "^2.166.0", "type": "peer" }, { diff --git a/.projenrc.ts b/.projenrc.ts index 43d7b922..29a33cc8 100644 --- a/.projenrc.ts +++ b/.projenrc.ts @@ -30,7 +30,7 @@ import { const GITHUB_USER = 'awslabs'; const PUBLICATION_NAMESPACE = 'cdklabs'; const PROJECT_NAME = 'generative-ai-cdk-constructs'; -const CDK_VERSION: string = '2.162.1'; +const CDK_VERSION: string = '2.166.0'; function camelCaseIt(input: string): string { // Hypens and dashes to spaces and then CamelCase... diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c9900ec..ab8857c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# CDK Generative AI Constructs V0.1.281 (2024-11-15) + +Based on CDK library version 2.166.0 + # CDK Generative AI Constructs V0.1.273 (2024-10-15) Based on CDK library version 2.162.1 diff --git a/DEVELOPER_GUIDE.md b/DEVELOPER_GUIDE.md index da9ab0bc..9118b64b 100644 --- a/DEVELOPER_GUIDE.md +++ b/DEVELOPER_GUIDE.md @@ -16,7 +16,7 @@ Default output format [None]: json ``` - [Node](https://nodejs.org/en) >= v20.9.0 -- [AWS CDK](https://github.com/aws/aws-cdk/releases/tag/v2.162.1) >= 2.162.1 +- [AWS CDK](https://github.com/aws/aws-cdk/releases/tag/v2.166.0) >= 2.166.0 - [Python](https://www.python.org/downloads/) >=3.9 - [Projen](https://github.com/projen/projen) >= 0.78.8 - [Yarn](https://classic.yarnpkg.com/lang/en/docs/cli/install/) >= 1.22.19 diff --git a/apidocs/interfaces/DockerLambdaCustomProps.md b/apidocs/interfaces/DockerLambdaCustomProps.md index eb99f594..51aa9785 100644 --- a/apidocs/interfaces/DockerLambdaCustomProps.md +++ b/apidocs/interfaces/DockerLambdaCustomProps.md @@ -594,7 +594,7 @@ stable > `readonly` `optional` **recursiveLoop**: `RecursiveLoop` Sets the Recursive Loop Protection for Lambda Function. -It lets Lambda detect and terminate unintended recusrive loops. +It lets Lambda detect and terminate unintended recursive loops. #### Default diff --git a/apidocs/namespaces/bedrock/classes/PromptVariant.md b/apidocs/namespaces/bedrock/classes/PromptVariant.md index 312882ea..c89038c4 100644 --- a/apidocs/namespaces/bedrock/classes/PromptVariant.md +++ b/apidocs/namespaces/bedrock/classes/PromptVariant.md @@ -46,9 +46,9 @@ The name of the prompt variant. *** -### templateConfiguration? +### templateConfiguration -> `abstract` `optional` **templateConfiguration**: `PromptTemplateConfigurationProperty` +> `abstract` **templateConfiguration**: `PromptTemplateConfigurationProperty` The template configuration. diff --git a/package.json b/package.json index 531a27fd..709f30bf 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ }, "devDependencies": { "@aws-cdk/assert": "^2.68.0", - "@aws-cdk/integ-tests-alpha": "2.162.1-alpha.0", + "@aws-cdk/integ-tests-alpha": "2.166.0-alpha.0", "@commitlint/config-conventional": "^18.6.3", "@mrgrain/jsii-struct-builder": "^0.7.43", "@types/jest": "^29.5.14", @@ -63,7 +63,7 @@ "@typescript-eslint/eslint-plugin": "^7", "@typescript-eslint/parser": "^7", "aws-cdk": "^2", - "aws-cdk-lib": "2.162.1", + "aws-cdk-lib": "2.166.0", "aws-sdk-mock": "^5.9.0", "commitlint": "^18.6.1", "constructs": "10.3.0", @@ -88,7 +88,7 @@ "typescript": "^5.6.3" }, "peerDependencies": { - "aws-cdk-lib": "^2.162.1", + "aws-cdk-lib": "^2.166.0", "constructs": "^10.3.0" }, "dependencies": { diff --git a/src/cdk-lib/bedrock/README.md b/src/cdk-lib/bedrock/README.md index 34ac28a3..b0bbb2f4 100644 --- a/src/cdk-lib/bedrock/README.md +++ b/src/cdk-lib/bedrock/README.md @@ -28,6 +28,8 @@ This construct library includes CloudFormation L1 resources to deploy Bedrock fe - [API](#api) - [Knowledge Bases](#knowledge-bases) - [Agents](#agents) +- [Guardrails](#bedrock-guardrails) +- [Prompt management](#prompt-management) ## API @@ -1016,7 +1018,7 @@ alias = bedrock.AgentAlias(self, 'ProdAlias', ) ``` -### Bedrock Guardrails +## Bedrock Guardrails Amazon Bedrock's Guardrails feature enables you to implement robust governance and control mechanisms for your generative AI applications, ensuring alignment with your specific use cases and responsible AI policies. Guardrails empowers you to create multiple tailored policy configurations, each designed to address the unique requirements and constraints of different use cases. These policy configurations can then be seamlessly applied across multiple foundation models (FMs) and Agents, ensuring a consistent user experience and standardizing safety, security, and privacy controls throughout your generative AI ecosystem. @@ -1227,7 +1229,6 @@ const variant1 = PromptVariant.text({ temperature: 1.0, topP: 0.999, maxTokens: 2000, - topK: 250, }, }); @@ -1264,7 +1265,6 @@ const variant2 = PromptVariant.text({ temperature: 0.5, topP: 0.999, maxTokens: 2000, - topK: 250, }, }); diff --git a/src/cdk-lib/bedrock/prompts/prompt.ts b/src/cdk-lib/bedrock/prompts/prompt.ts index 754e88a2..c4229dd2 100644 --- a/src/cdk-lib/bedrock/prompts/prompt.ts +++ b/src/cdk-lib/bedrock/prompts/prompt.ts @@ -102,7 +102,7 @@ export abstract class PromptVariant { /** * The template configuration. */ - public abstract templateConfiguration?: bedrock.CfnPrompt.PromptTemplateConfigurationProperty; + public abstract templateConfiguration: bedrock.CfnPrompt.PromptTemplateConfigurationProperty; // ------------------------------------------------------ // Constructor diff --git a/src/common/props/DockerLambdaCustomProps.ts b/src/common/props/DockerLambdaCustomProps.ts index dff6c541..2523169a 100644 --- a/src/common/props/DockerLambdaCustomProps.ts +++ b/src/common/props/DockerLambdaCustomProps.ts @@ -48,7 +48,7 @@ export interface DockerLambdaCustomProps { readonly reservedConcurrentExecutions?: number; /** * Sets the Recursive Loop Protection for Lambda Function. - * It lets Lambda detect and terminate unintended recusrive loops. + * It lets Lambda detect and terminate unintended recursive loops. * @default RecursiveLoop.Terminate * @stability stable */ diff --git a/test/cdk-lib/bedrock/prompts.test.ts b/test/cdk-lib/bedrock/prompts.test.ts index 16fcae64..c1feeb11 100644 --- a/test/cdk-lib/bedrock/prompts.test.ts +++ b/test/cdk-lib/bedrock/prompts.test.ts @@ -64,7 +64,6 @@ describe('Prompt', () => { temperature: 1.0, topP: 0.999, maxTokens: 2000, - topK: 250, }, }); @@ -87,7 +86,6 @@ describe('Prompt', () => { Text: { MaxTokens: 2000, Temperature: 1, - TopK: 250, TopP: 0.999, }, }, @@ -157,7 +155,6 @@ describe('Prompt', () => { temperature: 1.0, topP: 0.999, maxTokens: 2000, - topK: 250, }, }), ); diff --git a/yarn.lock b/yarn.lock index cfc17f2f..aaf907e5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17,12 +17,12 @@ dependencies: "@aws-cdk/cloudformation-diff" "2.68.0" -"@aws-cdk/asset-awscli-v1@^2.2.202": - version "2.2.210" - resolved "https://registry.yarnpkg.com/@aws-cdk/asset-awscli-v1/-/asset-awscli-v1-2.2.210.tgz#1bea0c6b4742ab2ed529c2f8344d41ae502a5679" - integrity sha512-yxuGP52ZtdAGkcAik5mW79FKKv6yvc5QuCZbsKMyICk48alqs+ni7Iv2UnuGLkVSLh09+ixoHHu4o5rIv8X9jg== +"@aws-cdk/asset-awscli-v1@^2.2.208": + version "2.2.211" + resolved "https://registry.yarnpkg.com/@aws-cdk/asset-awscli-v1/-/asset-awscli-v1-2.2.211.tgz#e33c1bab8e45ea3e4100fff1a0f4430a3ba2164d" + integrity sha512-56G1FYTiKyec3bEfEI/5UcU0XPnaGUlaDDH7OYClyvqss0HlnmoSulHK2gwai2PGAD1Nk+scPrdfH/MVAkSKuw== -"@aws-cdk/asset-kubectl-v20@^2.1.2": +"@aws-cdk/asset-kubectl-v20@^2.1.3": version "2.1.3" resolved "https://registry.yarnpkg.com/@aws-cdk/asset-kubectl-v20/-/asset-kubectl-v20-2.1.3.tgz#80e09004be173995e91614e34d947da11dd9ff4d" integrity sha512-cDG1w3ieM6eOT9mTefRuTypk95+oyD7P5X/wRltwmYxU7nZc3+076YEVS6vrjDKr3ADYbfn0lDKpfB1FBtO9CQ== @@ -40,7 +40,7 @@ fs-extra "^9.1.0" md5 "^2.3.0" -"@aws-cdk/cloud-assembly-schema@^38.0.0": +"@aws-cdk/cloud-assembly-schema@^38.0.1": version "38.0.1" resolved "https://registry.yarnpkg.com/@aws-cdk/cloud-assembly-schema/-/cloud-assembly-schema-38.0.1.tgz#cdf4684ae8778459e039cd44082ea644a3504ca9" integrity sha512-KvPe+NMWAulfNVwY7jenFhzhuLhLqJ/OPy5jx7wUstbjnYnjRVLpUHPU3yCjXFE0J8cuJVdx95BJ4rOs66Pi9w== @@ -60,10 +60,10 @@ string-width "^4.2.3" table "^6.8.1" -"@aws-cdk/integ-tests-alpha@2.162.1-alpha.0": - version "2.162.1-alpha.0" - resolved "https://registry.yarnpkg.com/@aws-cdk/integ-tests-alpha/-/integ-tests-alpha-2.162.1-alpha.0.tgz#576d1d8a0c88f25b683e319ec3e3b7ce94bf08c3" - integrity sha512-Y004DY4MEO/HtHIYvsGhS0T29RGiBjIguN37casoh8rosTXKVDDUKBBiXsF6d11qEAoQJfVKrRnHpj9LYcNWtQ== +"@aws-cdk/integ-tests-alpha@2.166.0-alpha.0": + version "2.166.0-alpha.0" + resolved "https://registry.yarnpkg.com/@aws-cdk/integ-tests-alpha/-/integ-tests-alpha-2.166.0-alpha.0.tgz#fc82a90c422cd0ff90ee4b3f72026b6eb900cd1b" + integrity sha512-ksM64XQP0FzzGxmVFQQDF8JIJKJpcfUoFWTvRghDMDNq8IBi/KsP4/gXpHDyl4jtS58EPOMBpsy0SRCFyOCVvw== "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.25.9", "@babel/code-frame@^7.26.0": version "7.26.2" @@ -1436,15 +1436,15 @@ available-typed-arrays@^1.0.7: dependencies: possible-typed-array-names "^1.0.0" -aws-cdk-lib@2.162.1: - version "2.162.1" - resolved "https://registry.yarnpkg.com/aws-cdk-lib/-/aws-cdk-lib-2.162.1.tgz#06454f1302a345dbd2a1866b0f170adbc93b1664" - integrity sha512-XiZLVE5ISNajNNmLye8l5w4EGqm6/d8C8shw63QwxaRVYdHl5e+EAaUEmZJpWc4sYtY/sS+GHOfhoKFLjha2rg== +aws-cdk-lib@2.166.0: + version "2.166.0" + resolved "https://registry.yarnpkg.com/aws-cdk-lib/-/aws-cdk-lib-2.166.0.tgz#279343451cc9391d52d77121e2a3feb2c756e3be" + integrity sha512-FAsIz/CpczbMrcShgvTWNp3kcGN6IDojJWNLqHioTRsTekcyN3OPmKvQJXUNWL0fnhTd8biFXC2esg6kM19xZw== dependencies: - "@aws-cdk/asset-awscli-v1" "^2.2.202" - "@aws-cdk/asset-kubectl-v20" "^2.1.2" + "@aws-cdk/asset-awscli-v1" "^2.2.208" + "@aws-cdk/asset-kubectl-v20" "^2.1.3" "@aws-cdk/asset-node-proxy-agent-v6" "^2.1.0" - "@aws-cdk/cloud-assembly-schema" "^38.0.0" + "@aws-cdk/cloud-assembly-schema" "^38.0.1" "@balena/dockerignore" "^1.0.2" case "1.6.3" fs-extra "^11.2.0" From dfbf49ec23a0e9973e037872f2b1c38a5b438b6a Mon Sep 17 00:00:00 2001 From: krokoko Date: Tue, 12 Nov 2024 16:29:34 -0600 Subject: [PATCH 02/22] feat(bedrock): add application inference profile --- apidocs/namespaces/bedrock/README.md | 2 + .../classes/ApplicationInferenceProfile.md | 144 ++++++++++++++++++ .../ApplicationInferenceProfileProps.md | 46 ++++++ src/cdk-lib/bedrock/README.md | 70 +++++++++ .../bedrock/application-inference-profile.ts | 92 +++++++++++ src/cdk-lib/bedrock/index.ts | 1 + .../application-inference-profile.test.ts | 68 +++++++++ 7 files changed, 423 insertions(+) create mode 100644 apidocs/namespaces/bedrock/classes/ApplicationInferenceProfile.md create mode 100644 apidocs/namespaces/bedrock/interfaces/ApplicationInferenceProfileProps.md create mode 100644 src/cdk-lib/bedrock/application-inference-profile.ts create mode 100644 test/cdk-lib/bedrock/application-inference-profile.test.ts diff --git a/apidocs/namespaces/bedrock/README.md b/apidocs/namespaces/bedrock/README.md index 8d094266..f634b364 100644 --- a/apidocs/namespaces/bedrock/README.md +++ b/apidocs/namespaces/bedrock/README.md @@ -41,6 +41,7 @@ - [AgentActionGroup](classes/AgentActionGroup.md) - [AgentAlias](classes/AgentAlias.md) - [ApiSchema](classes/ApiSchema.md) +- [ApplicationInferenceProfile](classes/ApplicationInferenceProfile.md) - [BedrockFoundationModel](classes/BedrockFoundationModel.md) - [ChunkingStrategy](classes/ChunkingStrategy.md) - [ConfluenceDataSource](classes/ConfluenceDataSource.md) @@ -72,6 +73,7 @@ - [AgentAliasProps](interfaces/AgentAliasProps.md) - [AgentProps](interfaces/AgentProps.md) - [ApiSchemaConfig](interfaces/ApiSchemaConfig.md) +- [ApplicationInferenceProfileProps](interfaces/ApplicationInferenceProfileProps.md) - [BedrockFoundationModelProps](interfaces/BedrockFoundationModelProps.md) - [CommonPromptVariantProps](interfaces/CommonPromptVariantProps.md) - [ConfluenceCrawlingFilters](interfaces/ConfluenceCrawlingFilters.md) diff --git a/apidocs/namespaces/bedrock/classes/ApplicationInferenceProfile.md b/apidocs/namespaces/bedrock/classes/ApplicationInferenceProfile.md new file mode 100644 index 00000000..9d74ea05 --- /dev/null +++ b/apidocs/namespaces/bedrock/classes/ApplicationInferenceProfile.md @@ -0,0 +1,144 @@ +[**@cdklabs/generative-ai-cdk-constructs**](../../../README.md) • **Docs** + +*** + +[@cdklabs/generative-ai-cdk-constructs](../../../README.md) / [bedrock](../README.md) / ApplicationInferenceProfile + +# Class: ApplicationInferenceProfile + +Creates an application inference profile. + +These are inference profiles created by users (user defined). +This helps to track costs and model usage. + +## Resource + +AWS::Bedrock::ApplicationInferenceProfile + +## See + +https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-create.html + +## Extends + +- `Construct` + +## Constructors + +### new ApplicationInferenceProfile() + +> **new ApplicationInferenceProfile**(`scope`, `id`, `props`): [`ApplicationInferenceProfile`](ApplicationInferenceProfile.md) + +#### Parameters + +• **scope**: `Construct` + +• **id**: `string` + +• **props**: [`ApplicationInferenceProfileProps`](../interfaces/ApplicationInferenceProfileProps.md) + +#### Returns + +[`ApplicationInferenceProfile`](ApplicationInferenceProfile.md) + +#### Overrides + +`Construct.constructor` + +## Properties + +### inferenceProfileArn + +> `readonly` **inferenceProfileArn**: `string` + +The ARN of the application inference profile. + +*** + +### inferenceProfileId + +> `readonly` **inferenceProfileId**: `string` + +The ARN of the application inference profile. + +*** + +### inferenceProfileIdentifier + +> `readonly` **inferenceProfileIdentifier**: `string` + +The unique identifier of the inference profile. + +*** + +### node + +> `readonly` **node**: `Node` + +The tree node. + +#### Inherited from + +`Construct.node` + +*** + +### status + +> `readonly` **status**: `string` + +The status of the inference profile. ACTIVE means that the inference profile is ready to be used. + +## Methods + +### toString() + +> **toString**(): `string` + +Returns a string representation of this construct. + +#### Returns + +`string` + +#### Inherited from + +`Construct.toString` + +*** + +### isConstruct() + +> `static` **isConstruct**(`x`): `x is Construct` + +Checks if `x` is a construct. + +Use this method instead of `instanceof` to properly detect `Construct` +instances, even when the construct library is symlinked. + +Explanation: in JavaScript, multiple copies of the `constructs` library on +disk are seen as independent, completely different libraries. As a +consequence, the class `Construct` in each copy of the `constructs` library +is seen as a different class, and an instance of one class will not test as +`instanceof` the other class. `npm install` will not create installations +like this, but users may manually symlink construct libraries together or +use a monorepo tool: in those cases, multiple copies of the `constructs` +library can be accidentally installed, and `instanceof` will behave +unpredictably. It is safest to avoid using `instanceof`, and using +this type-testing method instead. + +#### Parameters + +• **x**: `any` + +Any object + +#### Returns + +`x is Construct` + +true if `x` is an object created from a class which extends `Construct`. + +#### Inherited from + +`Construct.isConstruct` diff --git a/apidocs/namespaces/bedrock/interfaces/ApplicationInferenceProfileProps.md b/apidocs/namespaces/bedrock/interfaces/ApplicationInferenceProfileProps.md new file mode 100644 index 00000000..a2c8c469 --- /dev/null +++ b/apidocs/namespaces/bedrock/interfaces/ApplicationInferenceProfileProps.md @@ -0,0 +1,46 @@ +[**@cdklabs/generative-ai-cdk-constructs**](../../../README.md) • **Docs** + +*** + +[@cdklabs/generative-ai-cdk-constructs](../../../README.md) / [bedrock](../README.md) / ApplicationInferenceProfileProps + +# Interface: ApplicationInferenceProfileProps + +## Properties + +### description? + +> `readonly` `optional` **description**: `string` + +Description of the inference profile. + +#### See + +http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-bedrock-applicationinferenceprofile.html#cfn-bedrock-applicationinferenceprofile-description + +*** + +### inferenceProfileName + +> `readonly` **inferenceProfileName**: `string` + +The name of the inference profile. + +#### See + +http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-bedrock-applicationinferenceprofile.html#cfn-bedrock-applicationinferenceprofile-inferenceprofilename + +*** + +### modelSource + +> `readonly` **modelSource**: `string` + +To create an application inference profile for one Region, specify a foundation model. +Usage and costs for requests made to that Region with that model will be tracked. + +To create an application inference profile for multiple Regions, +specify a cross region (system-defined) inference profile. +The inference profile will route requests to the Regions defined in +the cross region (system-defined) inference profile that you choose. +Usage and costs for requests made to the Regions in the inference profile will be tracked. diff --git a/src/cdk-lib/bedrock/README.md b/src/cdk-lib/bedrock/README.md index b0bbb2f4..cb8db1f3 100644 --- a/src/cdk-lib/bedrock/README.md +++ b/src/cdk-lib/bedrock/README.md @@ -30,6 +30,7 @@ This construct library includes CloudFormation L1 resources to deploy Bedrock fe - [Agents](#agents) - [Guardrails](#bedrock-guardrails) - [Prompt management](#prompt-management) +- [Application inference profile](#application-inference-profile) ## API @@ -1294,3 +1295,72 @@ or alternatively: ```ts prompt1.createVersion("my first version"); ``` + +## Application inference profile + +You can create an application inference profile with one or more Regions to track usage and costs when invoking a model. + +To create an application inference profile for one Region, specify a foundation model. Usage and costs for requests made to that Region with that model will be tracked. + +To create an application inference profile for multiple Regions, specify a cross region (system-defined) inference profile. The inference profile will route requests to the Regions defined in the cross region (system-defined) inference profile that you choose. Usage and costs for requests made to the Regions in the inference profile will be tracked. You can find the system defined inference profiles by navigating to your console (Amazon Bedrock -> Cross-region inference) or programmatically, for instance using [boto3](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/bedrock/client/list_inference_profiles.html): +``` +bedrock = session.client("bedrock", region_name="us-east-1") +bedrock.list_inference_profiles(typeEquals='SYSTEM_DEFINED') +``` + +Before using application inference profiles, ensure that: +- You have appropriate IAM permissions +- You have access to the models and regions defined in the inference profiles +- Ensure proper configuration of the required API permissions for inference profile-related actions + +Specifically the role you are assuming needs to have permissions for following actions in the IAM policy +``` +"Action": [ + "bedrock:GetInferenceProfile", + "bedrock:ListInferenceProfiles", + "bedrock:DeleteInferenceProfile" + "bedrock:TagResource", + "bedrock:UntagResource", + "bedrock:ListTagsForResource" + ] +``` +You can restrict to specific resources by applying "Resources" tag in the IAM policy. +``` +"Resource": ["arn:aws:bedrock:*:*:application-inference-profile/*"] +``` + +TypeScript + +```ts +// Create an application inference profile for one Region +// You can use the 'bedrock.BedrockFoundationModel' or pass the arn as a string +const appInfProfile1 = new ApplicationInferenceProfile(this, 'myapplicationprofile', { + inferenceProfileName: 'claude 3 sonnet v1', + modelSource: bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0.asArn(stack) +}); + +// To create an application inference profile across regions, specify the cross region inference profile's ARN +const appInfProfile2 = new ApplicationInferenceProfile(this, 'myapplicationprofile2', { + inferenceProfileName: 'claude 3 sonnet v1', + modelSource: 'arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0' +}); + +``` + +Python + +```python + +# Create an application inference profile for one Region +# You can use the 'bedrock.BedrockFoundationModel' or pass the arn as a string +appInfProfile1 = ApplicationInferenceProfile(self, 'myapplicationprofile', + inference_profile_name: 'claude 3 sonnet v1', + model_source: bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0.asArn(stack) +) + +# To create an application inference profile across regions, specify the cross region inference profile's ARN +appInfProfile2 = new ApplicationInferenceProfile(self, 'myapplicationprofile2', + inference_profile_name: 'claude 35 sonnet v2', + model_source: 'arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0' +) +``` \ No newline at end of file diff --git a/src/cdk-lib/bedrock/application-inference-profile.ts b/src/cdk-lib/bedrock/application-inference-profile.ts new file mode 100644 index 00000000..954806d0 --- /dev/null +++ b/src/cdk-lib/bedrock/application-inference-profile.ts @@ -0,0 +1,92 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance + * with the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES + * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ +import { Construct } from 'constructs'; +import * as bedrock from 'aws-cdk-lib/aws-bedrock'; + +export interface ApplicationInferenceProfileProps { + /** + * Description of the inference profile. + * @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-bedrock-applicationinferenceprofile.html#cfn-bedrock-applicationinferenceprofile-description + */ + readonly description?: string; + /** + * The name of the inference profile. + * @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-bedrock-applicationinferenceprofile.html#cfn-bedrock-applicationinferenceprofile-inferenceprofilename + */ + readonly inferenceProfileName: string; + /** + * To create an application inference profile for one Region, specify a foundation model. + * Usage and costs for requests made to that Region with that model will be tracked. + * + * To create an application inference profile for multiple Regions, + * specify a cross region (system-defined) inference profile. + * The inference profile will route requests to the Regions defined in + * the cross region (system-defined) inference profile that you choose. + * Usage and costs for requests made to the Regions in the inference profile will be tracked. + */ + readonly modelSource: string; +} + +/** + * Creates an application inference profile. + * + * These are inference profiles created by users (user defined). + * This helps to track costs and model usage. + * @resource AWS::Bedrock::ApplicationInferenceProfile + * @see https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-create.html + */ +export class ApplicationInferenceProfile extends Construct { + /** + * The ARN of the application inference profile. + */ + public readonly inferenceProfileArn: string; + + /** + * The ARN of the application inference profile. + */ + public readonly inferenceProfileId: string; + + /** + * The unique identifier of the inference profile. + */ + public readonly inferenceProfileIdentifier: string; + + /** + * The status of the inference profile. ACTIVE means that the inference profile is ready to be used. + */ + public readonly status: string; + + /** + * Instance of CfnApplicationInferenceProfile. + */ + private readonly _resource: bedrock.CfnApplicationInferenceProfile; + + constructor(scope: Construct, id: string, props: ApplicationInferenceProfileProps) { + super(scope, id); + + // L1 instantiation + this._resource = new bedrock.CfnApplicationInferenceProfile(this, id, { + description: props.description, + inferenceProfileName: props.inferenceProfileName, + modelSource: { + copyFrom: props.modelSource, + }, + }); + + this.inferenceProfileArn = this._resource.attrInferenceProfileArn; + this.inferenceProfileId = this._resource.attrInferenceProfileId; + this.inferenceProfileIdentifier = this._resource.attrInferenceProfileIdentifier; + this.status = this._resource.attrStatus; + } + +} \ No newline at end of file diff --git a/src/cdk-lib/bedrock/index.ts b/src/cdk-lib/bedrock/index.ts index 721a97e1..02778fef 100644 --- a/src/cdk-lib/bedrock/index.ts +++ b/src/cdk-lib/bedrock/index.ts @@ -30,3 +30,4 @@ export * from './data-sources/sharepoint-data-source'; export * from './data-sources/confluence-data-source'; export * from './data-sources/salesforce-data-source'; export * from './data-sources/s3-data-source'; +export * from './application-inference-profile'; diff --git a/test/cdk-lib/bedrock/application-inference-profile.test.ts b/test/cdk-lib/bedrock/application-inference-profile.test.ts new file mode 100644 index 00000000..bd5159b9 --- /dev/null +++ b/test/cdk-lib/bedrock/application-inference-profile.test.ts @@ -0,0 +1,68 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance + * with the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES + * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ +import * as cdk from 'aws-cdk-lib'; +import { Match, Template } from 'aws-cdk-lib/assertions'; +import * as bedrock from '../../../src/cdk-lib/bedrock'; +import { AwsSolutionsChecks } from 'cdk-nag'; + +describe('CDK-Created-Application-Inference-Profile', () => { + let stack: cdk.Stack; + + beforeEach(() => { + const app = new cdk.App(); + cdk.Aspects.of(app).add(new AwsSolutionsChecks()); + stack = new cdk.Stack(app, 'TestStack'); + }); + + test('Basic Creation with a foundation model', () => { + new bedrock.ApplicationInferenceProfile(stack, 'TestAIP', { + inferenceProfileName: 'TestAIP', + description: 'This is a test application inf profile', + modelSource: bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0.asArn(stack) + }); + + Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::ApplicationInferenceProfile', { + InferenceProfileName: 'TestAIP', + Description: 'This is a test application inf profile', + ModelSource: { + CopyFrom: { + 'Fn::Join': [ + '', + [ + 'arn:aws:bedrock:', + { + Ref: 'AWS::Region', + }, + '::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0', + ], + ], + } + } + }); + }); + + test('Basic Creation with a system defined inference profile', () => { + new bedrock.ApplicationInferenceProfile(stack, 'TestAIPSystem', { + inferenceProfileName: 'TestAIPSystem', + modelSource: bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0.asArn(stack) + }); + + Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::ApplicationInferenceProfile', { + InferenceProfileName: 'TestAIPSystem', + Description: Match.absent(), + ModelSource: { + CopyFrom: 'arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0' + } + }); + }); +}); From a7b6e32d84856aec23337215d64e98785dc2cade Mon Sep 17 00:00:00 2001 From: krokoko Date: Tue, 12 Nov 2024 17:06:56 -0600 Subject: [PATCH 03/22] chore(build): fix mutation --- .../bedrock/application-inference-profile.ts | 84 +++++++++---------- .../application-inference-profile.test.ts | 36 ++++---- 2 files changed, 60 insertions(+), 60 deletions(-) diff --git a/src/cdk-lib/bedrock/application-inference-profile.ts b/src/cdk-lib/bedrock/application-inference-profile.ts index 954806d0..cd065ef4 100644 --- a/src/cdk-lib/bedrock/application-inference-profile.ts +++ b/src/cdk-lib/bedrock/application-inference-profile.ts @@ -10,83 +10,83 @@ * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions * and limitations under the License. */ -import { Construct } from 'constructs'; import * as bedrock from 'aws-cdk-lib/aws-bedrock'; +import { Construct } from 'constructs'; export interface ApplicationInferenceProfileProps { - /** + /** * Description of the inference profile. * @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-bedrock-applicationinferenceprofile.html#cfn-bedrock-applicationinferenceprofile-description */ - readonly description?: string; - /** + readonly description?: string; + /** * The name of the inference profile. * @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-bedrock-applicationinferenceprofile.html#cfn-bedrock-applicationinferenceprofile-inferenceprofilename */ - readonly inferenceProfileName: string; - /** - * To create an application inference profile for one Region, specify a foundation model. + readonly inferenceProfileName: string; + /** + * To create an application inference profile for one Region, specify a foundation model. * Usage and costs for requests made to that Region with that model will be tracked. - * - * To create an application inference profile for multiple Regions, - * specify a cross region (system-defined) inference profile. - * The inference profile will route requests to the Regions defined in - * the cross region (system-defined) inference profile that you choose. + * + * To create an application inference profile for multiple Regions, + * specify a cross region (system-defined) inference profile. + * The inference profile will route requests to the Regions defined in + * the cross region (system-defined) inference profile that you choose. * Usage and costs for requests made to the Regions in the inference profile will be tracked. */ - readonly modelSource: string; + readonly modelSource: string; } /** * Creates an application inference profile. * - * These are inference profiles created by users (user defined). + * These are inference profiles created by users (user defined). * This helps to track costs and model usage. * @resource AWS::Bedrock::ApplicationInferenceProfile * @see https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-create.html */ export class ApplicationInferenceProfile extends Construct { - /** + /** * The ARN of the application inference profile. */ - public readonly inferenceProfileArn: string; + public readonly inferenceProfileArn: string; - /** + /** * The ARN of the application inference profile. */ - public readonly inferenceProfileId: string; + public readonly inferenceProfileId: string; - /** + /** * The unique identifier of the inference profile. */ - public readonly inferenceProfileIdentifier: string; + public readonly inferenceProfileIdentifier: string; - /** + /** * The status of the inference profile. ACTIVE means that the inference profile is ready to be used. */ - public readonly status: string; + public readonly status: string; - /** + /** * Instance of CfnApplicationInferenceProfile. */ - private readonly _resource: bedrock.CfnApplicationInferenceProfile; - - constructor(scope: Construct, id: string, props: ApplicationInferenceProfileProps) { - super(scope, id); - - // L1 instantiation - this._resource = new bedrock.CfnApplicationInferenceProfile(this, id, { - description: props.description, - inferenceProfileName: props.inferenceProfileName, - modelSource: { - copyFrom: props.modelSource, - }, - }); + private readonly _resource: bedrock.CfnApplicationInferenceProfile; + + constructor(scope: Construct, id: string, props: ApplicationInferenceProfileProps) { + super(scope, id); + + // L1 instantiation + this._resource = new bedrock.CfnApplicationInferenceProfile(this, id, { + description: props.description, + inferenceProfileName: props.inferenceProfileName, + modelSource: { + copyFrom: props.modelSource, + }, + }); + + this.inferenceProfileArn = this._resource.attrInferenceProfileArn; + this.inferenceProfileId = this._resource.attrInferenceProfileId; + this.inferenceProfileIdentifier = this._resource.attrInferenceProfileIdentifier; + this.status = this._resource.attrStatus; + } - this.inferenceProfileArn = this._resource.attrInferenceProfileArn; - this.inferenceProfileId = this._resource.attrInferenceProfileId; - this.inferenceProfileIdentifier = this._resource.attrInferenceProfileIdentifier; - this.status = this._resource.attrStatus; - } - } \ No newline at end of file diff --git a/test/cdk-lib/bedrock/application-inference-profile.test.ts b/test/cdk-lib/bedrock/application-inference-profile.test.ts index d1dc8a82..1b010a1e 100644 --- a/test/cdk-lib/bedrock/application-inference-profile.test.ts +++ b/test/cdk-lib/bedrock/application-inference-profile.test.ts @@ -12,8 +12,8 @@ */ import * as cdk from 'aws-cdk-lib'; import { Match, Template } from 'aws-cdk-lib/assertions'; -import * as bedrock from '../../../src/cdk-lib/bedrock'; import { AwsSolutionsChecks } from 'cdk-nag'; +import * as bedrock from '../../../src/cdk-lib/bedrock'; describe('CDK-Created-Application-Inference-Profile', () => { let stack: cdk.Stack; @@ -26,9 +26,9 @@ describe('CDK-Created-Application-Inference-Profile', () => { test('Basic Creation with a foundation model', () => { new bedrock.ApplicationInferenceProfile(stack, 'TestAIP', { - inferenceProfileName: 'TestAIP', - description: 'This is a test application inf profile', - modelSource: bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0.asArn(stack) + inferenceProfileName: 'TestAIP', + description: 'This is a test application inf profile', + modelSource: bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0.asArn(stack), }); Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::ApplicationInferenceProfile', { @@ -37,32 +37,32 @@ describe('CDK-Created-Application-Inference-Profile', () => { ModelSource: { CopyFrom: { 'Fn::Join': [ - '', - [ - 'arn:aws:bedrock:', - { - Ref: 'AWS::Region', - }, - '::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0', - ], + '', + [ + 'arn:aws:bedrock:', + { + Ref: 'AWS::Region', + }, + '::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0', ], - } - } + ], + }, + }, }); }); test('Basic Creation with a system defined inference profile', () => { new bedrock.ApplicationInferenceProfile(stack, 'TestAIPSystem', { - inferenceProfileName: 'TestAIPSystem', - modelSource: 'arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0' + inferenceProfileName: 'TestAIPSystem', + modelSource: 'arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0', }); Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::ApplicationInferenceProfile', { InferenceProfileName: 'TestAIPSystem', Description: Match.absent(), ModelSource: { - CopyFrom: 'arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0' - } + CopyFrom: 'arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0', + }, }); }); }); From 724bf4faf853c5e371e428dcf0aac8b8923e38db Mon Sep 17 00:00:00 2001 From: krokoko Date: Tue, 12 Nov 2024 17:15:53 -0600 Subject: [PATCH 04/22] chore(build): fix mutation --- .../classes/ApplicationInferenceProfile.md | 15 ++++++++++++++- .../ApplicationInferenceProfileProps.md | 10 +++++----- .../bedrock/application-inference-profile.ts | 11 +++++++++++ 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/apidocs/namespaces/bedrock/classes/ApplicationInferenceProfile.md b/apidocs/namespaces/bedrock/classes/ApplicationInferenceProfile.md index 9d74ea05..4040825b 100644 --- a/apidocs/namespaces/bedrock/classes/ApplicationInferenceProfile.md +++ b/apidocs/namespaces/bedrock/classes/ApplicationInferenceProfile.md @@ -8,7 +8,7 @@ Creates an application inference profile. -These are inference profiles created by users (user defined). +These are inference profiles created by users (user defined). This helps to track costs and model usage. ## Resource @@ -89,6 +89,19 @@ The tree node. The status of the inference profile. ACTIVE means that the inference profile is ready to be used. +*** + +### type + +> `readonly` **type**: `string` + +The type of the inference profile. The following types are possible: +SYSTEM_DEFINED – The inference profile is defined by Amazon Bedrock. +You can route inference requests across regions with these inference profiles. +APPLICATION – The inference profile was created by a user. +This type of inference profile can track metrics and costs when invoking the model in it. +The inference profile may route requests to one or multiple regions. + ## Methods ### toString() diff --git a/apidocs/namespaces/bedrock/interfaces/ApplicationInferenceProfileProps.md b/apidocs/namespaces/bedrock/interfaces/ApplicationInferenceProfileProps.md index a2c8c469..ce079c41 100644 --- a/apidocs/namespaces/bedrock/interfaces/ApplicationInferenceProfileProps.md +++ b/apidocs/namespaces/bedrock/interfaces/ApplicationInferenceProfileProps.md @@ -36,11 +36,11 @@ http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-bedro > `readonly` **modelSource**: `string` -To create an application inference profile for one Region, specify a foundation model. +To create an application inference profile for one Region, specify a foundation model. Usage and costs for requests made to that Region with that model will be tracked. -To create an application inference profile for multiple Regions, -specify a cross region (system-defined) inference profile. -The inference profile will route requests to the Regions defined in -the cross region (system-defined) inference profile that you choose. +To create an application inference profile for multiple Regions, +specify a cross region (system-defined) inference profile. +The inference profile will route requests to the Regions defined in +the cross region (system-defined) inference profile that you choose. Usage and costs for requests made to the Regions in the inference profile will be tracked. diff --git a/src/cdk-lib/bedrock/application-inference-profile.ts b/src/cdk-lib/bedrock/application-inference-profile.ts index cd065ef4..ea4d2962 100644 --- a/src/cdk-lib/bedrock/application-inference-profile.ts +++ b/src/cdk-lib/bedrock/application-inference-profile.ts @@ -66,6 +66,16 @@ export class ApplicationInferenceProfile extends Construct { */ public readonly status: string; + /** + * The type of the inference profile. The following types are possible: + * SYSTEM_DEFINED – The inference profile is defined by Amazon Bedrock. + * You can route inference requests across regions with these inference profiles. + * APPLICATION – The inference profile was created by a user. + * This type of inference profile can track metrics and costs when invoking the model in it. + * The inference profile may route requests to one or multiple regions. + */ + public readonly type: string; + /** * Instance of CfnApplicationInferenceProfile. */ @@ -87,6 +97,7 @@ export class ApplicationInferenceProfile extends Construct { this.inferenceProfileId = this._resource.attrInferenceProfileId; this.inferenceProfileIdentifier = this._resource.attrInferenceProfileIdentifier; this.status = this._resource.attrStatus; + this.type = this._resource.attrType; } } \ No newline at end of file From f89f3e4e00f2733eec7d7f38ed37249a37ba40a4 Mon Sep 17 00:00:00 2001 From: krokoko Date: Wed, 13 Nov 2024 16:59:31 -0600 Subject: [PATCH 05/22] chore(refactor): update design and add from methods --- apidocs/namespaces/bedrock/README.md | 3 + .../classes/ApplicationInferenceProfile.md | 297 +++++++++++++- .../ApplicationInferenceProfileBase.md | 378 ++++++++++++++++++ ...plicationInferenceApplicationAttributes.md | 35 ++ .../ApplicationInferenceProfileProps.md | 10 + .../IApplicationInferenceProfile.md | 107 +++++ src/cdk-lib/bedrock/README.md | 53 ++- .../bedrock/application-inference-profile.ts | 127 +++++- .../application-inference-profile.test.ts | 56 +++ 9 files changed, 1039 insertions(+), 27 deletions(-) create mode 100644 apidocs/namespaces/bedrock/classes/ApplicationInferenceProfileBase.md create mode 100644 apidocs/namespaces/bedrock/interfaces/ApplicationInferenceApplicationAttributes.md create mode 100644 apidocs/namespaces/bedrock/interfaces/IApplicationInferenceProfile.md diff --git a/apidocs/namespaces/bedrock/README.md b/apidocs/namespaces/bedrock/README.md index f634b364..7c663090 100644 --- a/apidocs/namespaces/bedrock/README.md +++ b/apidocs/namespaces/bedrock/README.md @@ -42,6 +42,7 @@ - [AgentAlias](classes/AgentAlias.md) - [ApiSchema](classes/ApiSchema.md) - [ApplicationInferenceProfile](classes/ApplicationInferenceProfile.md) +- [ApplicationInferenceProfileBase](classes/ApplicationInferenceProfileBase.md) - [BedrockFoundationModel](classes/BedrockFoundationModel.md) - [ChunkingStrategy](classes/ChunkingStrategy.md) - [ConfluenceDataSource](classes/ConfluenceDataSource.md) @@ -73,6 +74,7 @@ - [AgentAliasProps](interfaces/AgentAliasProps.md) - [AgentProps](interfaces/AgentProps.md) - [ApiSchemaConfig](interfaces/ApiSchemaConfig.md) +- [ApplicationInferenceApplicationAttributes](interfaces/ApplicationInferenceApplicationAttributes.md) - [ApplicationInferenceProfileProps](interfaces/ApplicationInferenceProfileProps.md) - [BedrockFoundationModelProps](interfaces/BedrockFoundationModelProps.md) - [CommonPromptVariantProps](interfaces/CommonPromptVariantProps.md) @@ -90,6 +92,7 @@ - [GuardrailProps](interfaces/GuardrailProps.md) - [HierarchicalChunkingProps](interfaces/HierarchicalChunkingProps.md) - [IAgentAlias](interfaces/IAgentAlias.md) +- [IApplicationInferenceProfile](interfaces/IApplicationInferenceProfile.md) - [IDataSource](interfaces/IDataSource.md) - [IGuardrail](interfaces/IGuardrail.md) - [IKnowledgeBase](interfaces/IKnowledgeBase.md) diff --git a/apidocs/namespaces/bedrock/classes/ApplicationInferenceProfile.md b/apidocs/namespaces/bedrock/classes/ApplicationInferenceProfile.md index 4040825b..5d3cb454 100644 --- a/apidocs/namespaces/bedrock/classes/ApplicationInferenceProfile.md +++ b/apidocs/namespaces/bedrock/classes/ApplicationInferenceProfile.md @@ -6,8 +6,7 @@ # Class: ApplicationInferenceProfile -Creates an application inference profile. - +Class to create a ApplicationInferenceProfile with CDK. These are inference profiles created by users (user defined). This helps to track costs and model usage. @@ -21,7 +20,7 @@ https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-create.h ## Extends -- `Construct` +- [`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md) ## Constructors @@ -43,23 +42,57 @@ https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-create.h #### Overrides -`Construct.constructor` +[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md).[`constructor`](ApplicationInferenceProfileBase.md#constructors) ## Properties +### createdAt + +> `readonly` **createdAt**: `string` + +Time Stamp for ApplicationInferenceProfile creation. + +*** + +### env + +> `readonly` **env**: `ResourceEnvironment` + +The environment this resource belongs to. +For resources that are created and managed by the CDK +(generally, those created by creating new class instances like Role, Bucket, etc.), +this is always the same as the environment of the stack they belong to; +however, for imported resources +(those obtained from static methods like fromRoleArn, fromBucketName, etc.), +that might be different than the stack they were imported into. + +#### Inherited from + +[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md).[`env`](ApplicationInferenceProfileBase.md#env) + +*** + ### inferenceProfileArn > `readonly` **inferenceProfileArn**: `string` The ARN of the application inference profile. +#### Overrides + +[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md).[`inferenceProfileArn`](ApplicationInferenceProfileBase.md#inferenceprofilearn) + *** ### inferenceProfileId > `readonly` **inferenceProfileId**: `string` -The ARN of the application inference profile. +The unique identifier of the inference profile. + +#### Overrides + +[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md).[`inferenceProfileId`](ApplicationInferenceProfileBase.md#inferenceprofileid) *** @@ -67,7 +100,11 @@ The ARN of the application inference profile. > `readonly` **inferenceProfileIdentifier**: `string` -The unique identifier of the inference profile. +The ID or Amazon Resource Name (ARN) of the inference profile. + +#### Overrides + +[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md).[`inferenceProfileIdentifier`](ApplicationInferenceProfileBase.md#inferenceprofileidentifier) *** @@ -79,7 +116,38 @@ The tree node. #### Inherited from -`Construct.node` +[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md).[`node`](ApplicationInferenceProfileBase.md#node) + +*** + +### physicalName + +> `protected` `readonly` **physicalName**: `string` + +Returns a string-encoded token that resolves to the physical name that +should be passed to the CloudFormation resource. + +This value will resolve to one of the following: +- a concrete value (e.g. `"my-awesome-bucket"`) +- `undefined`, when a name should be generated by CloudFormation +- a concrete name generated automatically during synthesis, in + cross-environment scenarios. + +#### Inherited from + +[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md).[`physicalName`](ApplicationInferenceProfileBase.md#physicalname) + +*** + +### stack + +> `readonly` **stack**: `Stack` + +The stack in which this resource is defined. + +#### Inherited from + +[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md).[`stack`](ApplicationInferenceProfileBase.md#stack) *** @@ -102,8 +170,143 @@ APPLICATION – The inference profile was created by a user. This type of inference profile can track metrics and costs when invoking the model in it. The inference profile may route requests to one or multiple regions. +*** + +### updatedAt + +> `readonly` **updatedAt**: `string` + +Time Stamp for ApplicationInferenceProfile update. + ## Methods +### \_enableCrossEnvironment() + +> **\_enableCrossEnvironment**(): `void` + +**`Internal`** + +Called when this resource is referenced across environments +(account/region) to order to request that a physical name will be generated +for this resource during synthesis, so the resource can be referenced +through its absolute name/arn. + +#### Returns + +`void` + +#### Inherited from + +[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md).[`_enableCrossEnvironment`](ApplicationInferenceProfileBase.md#_enablecrossenvironment) + +*** + +### applyRemovalPolicy() + +> **applyRemovalPolicy**(`policy`): `void` + +Apply the given removal policy to this resource + +The Removal Policy controls what happens to this resource when it stops +being managed by CloudFormation, either because you've removed it from the +CDK application or because you've made a change that requires the resource +to be replaced. + +The resource can be deleted (`RemovalPolicy.DESTROY`), or left in your AWS +account for data recovery and cleanup later (`RemovalPolicy.RETAIN`). + +#### Parameters + +• **policy**: `RemovalPolicy` + +#### Returns + +`void` + +#### Inherited from + +[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md).[`applyRemovalPolicy`](ApplicationInferenceProfileBase.md#applyremovalpolicy) + +*** + +### generatePhysicalName() + +> `protected` **generatePhysicalName**(): `string` + +#### Returns + +`string` + +#### Inherited from + +[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md).[`generatePhysicalName`](ApplicationInferenceProfileBase.md#generatephysicalname) + +*** + +### getResourceArnAttribute() + +> `protected` **getResourceArnAttribute**(`arnAttr`, `arnComponents`): `string` + +Returns an environment-sensitive token that should be used for the +resource's "ARN" attribute (e.g. `bucket.bucketArn`). + +Normally, this token will resolve to `arnAttr`, but if the resource is +referenced across environments, `arnComponents` will be used to synthesize +a concrete ARN with the resource's physical name. Make sure to reference +`this.physicalName` in `arnComponents`. + +#### Parameters + +• **arnAttr**: `string` + +The CFN attribute which resolves to the ARN of the resource. +Commonly it will be called "Arn" (e.g. `resource.attrArn`), but sometimes +it's the CFN resource's `ref`. + +• **arnComponents**: `ArnComponents` + +The format of the ARN of this resource. You must +reference `this.physicalName` somewhere within the ARN in order for +cross-environment references to work. + +#### Returns + +`string` + +#### Inherited from + +[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md).[`getResourceArnAttribute`](ApplicationInferenceProfileBase.md#getresourcearnattribute) + +*** + +### getResourceNameAttribute() + +> `protected` **getResourceNameAttribute**(`nameAttr`): `string` + +Returns an environment-sensitive token that should be used for the +resource's "name" attribute (e.g. `bucket.bucketName`). + +Normally, this token will resolve to `nameAttr`, but if the resource is +referenced across environments, it will be resolved to `this.physicalName`, +which will be a concrete name. + +#### Parameters + +• **nameAttr**: `string` + +The CFN attribute which resolves to the resource's name. +Commonly this is the resource's `ref`. + +#### Returns + +`string` + +#### Inherited from + +[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md).[`getResourceNameAttribute`](ApplicationInferenceProfileBase.md#getresourcenameattribute) + +*** + ### toString() > **toString**(): `string` @@ -116,7 +319,43 @@ Returns a string representation of this construct. #### Inherited from -`Construct.toString` +[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md).[`toString`](ApplicationInferenceProfileBase.md#tostring) + +*** + +### fromApplicationInferenceProfileAttributes() + +> `static` **fromApplicationInferenceProfileAttributes**(`scope`, `id`, `attrs`): [`IApplicationInferenceProfile`](../interfaces/IApplicationInferenceProfile.md) + +Import a ApplicationInferenceProfile given its attributes + +#### Parameters + +• **scope**: `Construct` + +• **id**: `string` + +• **attrs**: [`ApplicationInferenceApplicationAttributes`](../interfaces/ApplicationInferenceApplicationAttributes.md) + +#### Returns + +[`IApplicationInferenceProfile`](../interfaces/IApplicationInferenceProfile.md) + +*** + +### fromCfnApplicationInferenceProfile() + +> `static` **fromCfnApplicationInferenceProfile**(`CfnApplicationInferenceProfile`): [`IApplicationInferenceProfile`](../interfaces/IApplicationInferenceProfile.md) + +Import a low-level L1 Cfn ApplicationInferenceProfile + +#### Parameters + +• **CfnApplicationInferenceProfile**: `CfnApplicationInferenceProfile` + +#### Returns + +[`IApplicationInferenceProfile`](../interfaces/IApplicationInferenceProfile.md) *** @@ -154,4 +393,44 @@ true if `x` is an object created from a class which extends `Construct`. #### Inherited from -`Construct.isConstruct` +[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md).[`isConstruct`](ApplicationInferenceProfileBase.md#isconstruct) + +*** + +### isOwnedResource() + +> `static` **isOwnedResource**(`construct`): `boolean` + +Returns true if the construct was created by CDK, and false otherwise + +#### Parameters + +• **construct**: `IConstruct` + +#### Returns + +`boolean` + +#### Inherited from + +[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md).[`isOwnedResource`](ApplicationInferenceProfileBase.md#isownedresource) + +*** + +### isResource() + +> `static` **isResource**(`construct`): `construct is Resource` + +Check whether the given construct is a Resource + +#### Parameters + +• **construct**: `IConstruct` + +#### Returns + +`construct is Resource` + +#### Inherited from + +[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md).[`isResource`](ApplicationInferenceProfileBase.md#isresource) diff --git a/apidocs/namespaces/bedrock/classes/ApplicationInferenceProfileBase.md b/apidocs/namespaces/bedrock/classes/ApplicationInferenceProfileBase.md new file mode 100644 index 00000000..6aa7c3c2 --- /dev/null +++ b/apidocs/namespaces/bedrock/classes/ApplicationInferenceProfileBase.md @@ -0,0 +1,378 @@ +[**@cdklabs/generative-ai-cdk-constructs**](../../../README.md) • **Docs** + +*** + +[@cdklabs/generative-ai-cdk-constructs](../../../README.md) / [bedrock](../README.md) / ApplicationInferenceProfileBase + +# Class: `abstract` ApplicationInferenceProfileBase + +Abstract base class for a ApplicationInferenceProfile. +Contains methods and attributes valid for ApplicationInferenceProfiles either created with CDK or imported. + +## Extends + +- `Resource` + +## Extended by + +- [`ApplicationInferenceProfile`](ApplicationInferenceProfile.md) + +## Implements + +- [`IApplicationInferenceProfile`](../interfaces/IApplicationInferenceProfile.md) + +## Constructors + +### new ApplicationInferenceProfileBase() + +> **new ApplicationInferenceProfileBase**(`scope`, `id`, `props`?): [`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md) + +#### Parameters + +• **scope**: `Construct` + +• **id**: `string` + +• **props?**: `ResourceProps` + +#### Returns + +[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md) + +#### Inherited from + +`Resource.constructor` + +## Properties + +### env + +> `readonly` **env**: `ResourceEnvironment` + +The environment this resource belongs to. +For resources that are created and managed by the CDK +(generally, those created by creating new class instances like Role, Bucket, etc.), +this is always the same as the environment of the stack they belong to; +however, for imported resources +(those obtained from static methods like fromRoleArn, fromBucketName, etc.), +that might be different than the stack they were imported into. + +#### Implementation of + +[`IApplicationInferenceProfile`](../interfaces/IApplicationInferenceProfile.md).[`env`](../interfaces/IApplicationInferenceProfile.md#env) + +#### Inherited from + +`Resource.env` + +*** + +### inferenceProfileArn + +> `abstract` `readonly` **inferenceProfileArn**: `string` + +The ARN of the application inference profile. + +#### Implementation of + +[`IApplicationInferenceProfile`](../interfaces/IApplicationInferenceProfile.md).[`inferenceProfileArn`](../interfaces/IApplicationInferenceProfile.md#inferenceprofilearn) + +*** + +### inferenceProfileId + +> `abstract` `readonly` **inferenceProfileId**: `string` + +The unique identifier of the inference profile. + +#### Implementation of + +[`IApplicationInferenceProfile`](../interfaces/IApplicationInferenceProfile.md).[`inferenceProfileId`](../interfaces/IApplicationInferenceProfile.md#inferenceprofileid) + +*** + +### inferenceProfileIdentifier + +> `abstract` `readonly` **inferenceProfileIdentifier**: `string` + +The ID or Amazon Resource Name (ARN) of the inference profile. + +#### Implementation of + +[`IApplicationInferenceProfile`](../interfaces/IApplicationInferenceProfile.md).[`inferenceProfileIdentifier`](../interfaces/IApplicationInferenceProfile.md#inferenceprofileidentifier) + +*** + +### node + +> `readonly` **node**: `Node` + +The tree node. + +#### Implementation of + +[`IApplicationInferenceProfile`](../interfaces/IApplicationInferenceProfile.md).[`node`](../interfaces/IApplicationInferenceProfile.md#node) + +#### Inherited from + +`Resource.node` + +*** + +### physicalName + +> `protected` `readonly` **physicalName**: `string` + +Returns a string-encoded token that resolves to the physical name that +should be passed to the CloudFormation resource. + +This value will resolve to one of the following: +- a concrete value (e.g. `"my-awesome-bucket"`) +- `undefined`, when a name should be generated by CloudFormation +- a concrete name generated automatically during synthesis, in + cross-environment scenarios. + +#### Inherited from + +`Resource.physicalName` + +*** + +### stack + +> `readonly` **stack**: `Stack` + +The stack in which this resource is defined. + +#### Implementation of + +[`IApplicationInferenceProfile`](../interfaces/IApplicationInferenceProfile.md).[`stack`](../interfaces/IApplicationInferenceProfile.md#stack) + +#### Inherited from + +`Resource.stack` + +## Methods + +### \_enableCrossEnvironment() + +> **\_enableCrossEnvironment**(): `void` + +**`Internal`** + +Called when this resource is referenced across environments +(account/region) to order to request that a physical name will be generated +for this resource during synthesis, so the resource can be referenced +through its absolute name/arn. + +#### Returns + +`void` + +#### Inherited from + +`Resource._enableCrossEnvironment` + +*** + +### applyRemovalPolicy() + +> **applyRemovalPolicy**(`policy`): `void` + +Apply the given removal policy to this resource + +The Removal Policy controls what happens to this resource when it stops +being managed by CloudFormation, either because you've removed it from the +CDK application or because you've made a change that requires the resource +to be replaced. + +The resource can be deleted (`RemovalPolicy.DESTROY`), or left in your AWS +account for data recovery and cleanup later (`RemovalPolicy.RETAIN`). + +#### Parameters + +• **policy**: `RemovalPolicy` + +#### Returns + +`void` + +#### Implementation of + +[`IApplicationInferenceProfile`](../interfaces/IApplicationInferenceProfile.md).[`applyRemovalPolicy`](../interfaces/IApplicationInferenceProfile.md#applyremovalpolicy) + +#### Inherited from + +`Resource.applyRemovalPolicy` + +*** + +### generatePhysicalName() + +> `protected` **generatePhysicalName**(): `string` + +#### Returns + +`string` + +#### Inherited from + +`Resource.generatePhysicalName` + +*** + +### getResourceArnAttribute() + +> `protected` **getResourceArnAttribute**(`arnAttr`, `arnComponents`): `string` + +Returns an environment-sensitive token that should be used for the +resource's "ARN" attribute (e.g. `bucket.bucketArn`). + +Normally, this token will resolve to `arnAttr`, but if the resource is +referenced across environments, `arnComponents` will be used to synthesize +a concrete ARN with the resource's physical name. Make sure to reference +`this.physicalName` in `arnComponents`. + +#### Parameters + +• **arnAttr**: `string` + +The CFN attribute which resolves to the ARN of the resource. +Commonly it will be called "Arn" (e.g. `resource.attrArn`), but sometimes +it's the CFN resource's `ref`. + +• **arnComponents**: `ArnComponents` + +The format of the ARN of this resource. You must +reference `this.physicalName` somewhere within the ARN in order for +cross-environment references to work. + +#### Returns + +`string` + +#### Inherited from + +`Resource.getResourceArnAttribute` + +*** + +### getResourceNameAttribute() + +> `protected` **getResourceNameAttribute**(`nameAttr`): `string` + +Returns an environment-sensitive token that should be used for the +resource's "name" attribute (e.g. `bucket.bucketName`). + +Normally, this token will resolve to `nameAttr`, but if the resource is +referenced across environments, it will be resolved to `this.physicalName`, +which will be a concrete name. + +#### Parameters + +• **nameAttr**: `string` + +The CFN attribute which resolves to the resource's name. +Commonly this is the resource's `ref`. + +#### Returns + +`string` + +#### Inherited from + +`Resource.getResourceNameAttribute` + +*** + +### toString() + +> **toString**(): `string` + +Returns a string representation of this construct. + +#### Returns + +`string` + +#### Inherited from + +`Resource.toString` + +*** + +### isConstruct() + +> `static` **isConstruct**(`x`): `x is Construct` + +Checks if `x` is a construct. + +Use this method instead of `instanceof` to properly detect `Construct` +instances, even when the construct library is symlinked. + +Explanation: in JavaScript, multiple copies of the `constructs` library on +disk are seen as independent, completely different libraries. As a +consequence, the class `Construct` in each copy of the `constructs` library +is seen as a different class, and an instance of one class will not test as +`instanceof` the other class. `npm install` will not create installations +like this, but users may manually symlink construct libraries together or +use a monorepo tool: in those cases, multiple copies of the `constructs` +library can be accidentally installed, and `instanceof` will behave +unpredictably. It is safest to avoid using `instanceof`, and using +this type-testing method instead. + +#### Parameters + +• **x**: `any` + +Any object + +#### Returns + +`x is Construct` + +true if `x` is an object created from a class which extends `Construct`. + +#### Inherited from + +`Resource.isConstruct` + +*** + +### isOwnedResource() + +> `static` **isOwnedResource**(`construct`): `boolean` + +Returns true if the construct was created by CDK, and false otherwise + +#### Parameters + +• **construct**: `IConstruct` + +#### Returns + +`boolean` + +#### Inherited from + +`Resource.isOwnedResource` + +*** + +### isResource() + +> `static` **isResource**(`construct`): `construct is Resource` + +Check whether the given construct is a Resource + +#### Parameters + +• **construct**: `IConstruct` + +#### Returns + +`construct is Resource` + +#### Inherited from + +`Resource.isResource` diff --git a/apidocs/namespaces/bedrock/interfaces/ApplicationInferenceApplicationAttributes.md b/apidocs/namespaces/bedrock/interfaces/ApplicationInferenceApplicationAttributes.md new file mode 100644 index 00000000..1bb986b8 --- /dev/null +++ b/apidocs/namespaces/bedrock/interfaces/ApplicationInferenceApplicationAttributes.md @@ -0,0 +1,35 @@ +[**@cdklabs/generative-ai-cdk-constructs**](../../../README.md) • **Docs** + +*** + +[@cdklabs/generative-ai-cdk-constructs](../../../README.md) / [bedrock](../README.md) / ApplicationInferenceApplicationAttributes + +# Interface: ApplicationInferenceApplicationAttributes + +*************************************************************************** + ATTRS FOR IMPORTED CONSTRUCT +*************************************************************************** + +## Properties + +### inferenceProfileArn + +> `readonly` **inferenceProfileArn**: `string` + +The ARN of the application inference profile. + +*** + +### inferenceProfileId + +> `readonly` **inferenceProfileId**: `string` + +The unique identifier of the inference profile. + +*** + +### inferenceProfileIdentifier + +> `readonly` **inferenceProfileIdentifier**: `string` + +The ID or Amazon Resource Name (ARN) of the inference profile. diff --git a/apidocs/namespaces/bedrock/interfaces/ApplicationInferenceProfileProps.md b/apidocs/namespaces/bedrock/interfaces/ApplicationInferenceProfileProps.md index ce079c41..1c2fbd62 100644 --- a/apidocs/namespaces/bedrock/interfaces/ApplicationInferenceProfileProps.md +++ b/apidocs/namespaces/bedrock/interfaces/ApplicationInferenceProfileProps.md @@ -6,6 +6,8 @@ # Interface: ApplicationInferenceProfileProps +Properties for creating a ApplicationInferenceProfile. + ## Properties ### description? @@ -44,3 +46,11 @@ specify a cross region (system-defined) inference profile. The inference profile will route requests to the Regions defined in the cross region (system-defined) inference profile that you choose. Usage and costs for requests made to the Regions in the inference profile will be tracked. + +*** + +### tags? + +> `readonly` `optional` **tags**: `CfnTag`[] + +A list of tags associated with the inference profile. diff --git a/apidocs/namespaces/bedrock/interfaces/IApplicationInferenceProfile.md b/apidocs/namespaces/bedrock/interfaces/IApplicationInferenceProfile.md new file mode 100644 index 00000000..45af9036 --- /dev/null +++ b/apidocs/namespaces/bedrock/interfaces/IApplicationInferenceProfile.md @@ -0,0 +1,107 @@ +[**@cdklabs/generative-ai-cdk-constructs**](../../../README.md) • **Docs** + +*** + +[@cdklabs/generative-ai-cdk-constructs](../../../README.md) / [bedrock](../README.md) / IApplicationInferenceProfile + +# Interface: IApplicationInferenceProfile + +Represents a ApplicationInferenceProfile, either created with CDK or imported. + +## Extends + +- `IResource` + +## Properties + +### env + +> `readonly` **env**: `ResourceEnvironment` + +The environment this resource belongs to. +For resources that are created and managed by the CDK +(generally, those created by creating new class instances like Role, Bucket, etc.), +this is always the same as the environment of the stack they belong to; +however, for imported resources +(those obtained from static methods like fromRoleArn, fromBucketName, etc.), +that might be different than the stack they were imported into. + +#### Inherited from + +`IResource.env` + +*** + +### inferenceProfileArn + +> `readonly` **inferenceProfileArn**: `string` + +The ARN of the application inference profile. + +*** + +### inferenceProfileId + +> `readonly` **inferenceProfileId**: `string` + +The unique identifier of the inference profile. + +*** + +### inferenceProfileIdentifier + +> `readonly` **inferenceProfileIdentifier**: `string` + +The ID or Amazon Resource Name (ARN) of the inference profile. + +*** + +### node + +> `readonly` **node**: `Node` + +The tree node. + +#### Inherited from + +`IResource.node` + +*** + +### stack + +> `readonly` **stack**: `Stack` + +The stack in which this resource is defined. + +#### Inherited from + +`IResource.stack` + +## Methods + +### applyRemovalPolicy() + +> **applyRemovalPolicy**(`policy`): `void` + +Apply the given removal policy to this resource + +The Removal Policy controls what happens to this resource when it stops +being managed by CloudFormation, either because you've removed it from the +CDK application or because you've made a change that requires the resource +to be replaced. + +The resource can be deleted (`RemovalPolicy.DESTROY`), or left in your AWS +account for data recovery and cleanup later (`RemovalPolicy.RETAIN`). + +#### Parameters + +• **policy**: `RemovalPolicy` + +#### Returns + +`void` + +#### Inherited from + +`IResource.applyRemovalPolicy` diff --git a/src/cdk-lib/bedrock/README.md b/src/cdk-lib/bedrock/README.md index cb8db1f3..278302ab 100644 --- a/src/cdk-lib/bedrock/README.md +++ b/src/cdk-lib/bedrock/README.md @@ -1336,7 +1336,8 @@ TypeScript // You can use the 'bedrock.BedrockFoundationModel' or pass the arn as a string const appInfProfile1 = new ApplicationInferenceProfile(this, 'myapplicationprofile', { inferenceProfileName: 'claude 3 sonnet v1', - modelSource: bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0.asArn(stack) + modelSource: bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0.asArn(stack), + tags: [{key: 'test', value: 'test'}] }); // To create an application inference profile across regions, specify the cross region inference profile's ARN @@ -1345,6 +1346,23 @@ const appInfProfile2 = new ApplicationInferenceProfile(this, 'myapplicationprofi modelSource: 'arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0' }); +// Import a Cfn L1 construct created application inference profile +const cfnapp = new CfnApplicationInferenceProfile(this, 'mytestaip3', { + inferenceProfileName: 'mytest', + modelSource: { + copyFrom: 'arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0', + }, +}); + +const appInfProfile3 = bedrock.ApplicationInferenceProfile.fromCfnApplicationInferenceProfile(cfnapp); + +// Import an inference profile through attributes +const appInfProfile4 = bedrock.ApplicationInferenceProfile.fromApplicationInferenceProfileAttributes(this, 'TestAIP', { + inferenceProfileArn: 'arn:aws:bedrock:us-east-1:XXXXX:application-inference-profile/ID', + inferenceProfileId: 'ID', + inferenceProfileIdentifier: 'arn:aws:bedrock:us-east-1:XXXXXXX:application-inference-profile/ID', +}); + ``` Python @@ -1353,14 +1371,35 @@ Python # Create an application inference profile for one Region # You can use the 'bedrock.BedrockFoundationModel' or pass the arn as a string -appInfProfile1 = ApplicationInferenceProfile(self, 'myapplicationprofile', - inference_profile_name: 'claude 3 sonnet v1', - model_source: bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0.asArn(stack) +appInfProfile1 = bedrock.ApplicationInferenceProfile(self, 'myapplicationprofile', + inference_profile_name='claude 3 sonnet v1', + model_source=bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0.asArn(stack), + tags=[CfnTag( + key="key", + value="value" + )] ) # To create an application inference profile across regions, specify the cross region inference profile's ARN -appInfProfile2 = new ApplicationInferenceProfile(self, 'myapplicationprofile2', - inference_profile_name: 'claude 35 sonnet v2', - model_source: 'arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0' +appInfProfile2 = bedrock.ApplicationInferenceProfile(self, 'myapplicationprofile2', + inference_profile_name='claude 35 sonnet v2', + model_source='arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0' ) + +# Import an inference profile through attributes +appInfProfile3 = bedrock.ApplicationInferenceProfile.from_application_inference_profile_attributes(self, 'TestAIP', + inference_profile_arn='arn:aws:bedrock:us-east-1:XXXXX:application-inference-profile/ID', + inference_profile_id='ID', + inference_profile_identifier='arn:aws:bedrock:us-east-1:XXXXXXX:application-inference-profile/ID', +) + +# Import a Cfn L1 construct created application inference profile +cfnaip = CfnApplicationInferenceProfile(this, 'mytestaip4', + inference_profile_name='mytest', + model_source= CfnApplicationInferenceProfile.InferenceProfileModelSourceProperty( + copy_from='arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0' + ), +) + +appInfProfile4 = bedrock.ApplicationInferenceProfile.from_cfn_application_inference_profile(cfnaip); ``` \ No newline at end of file diff --git a/src/cdk-lib/bedrock/application-inference-profile.ts b/src/cdk-lib/bedrock/application-inference-profile.ts index ea4d2962..a1c86d77 100644 --- a/src/cdk-lib/bedrock/application-inference-profile.ts +++ b/src/cdk-lib/bedrock/application-inference-profile.ts @@ -10,9 +10,56 @@ * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions * and limitations under the License. */ +import { IResource, Resource, CfnTag } from 'aws-cdk-lib'; import * as bedrock from 'aws-cdk-lib/aws-bedrock'; import { Construct } from 'constructs'; +/****************************************************************************** + * COMMON + *****************************************************************************/ +/** + * Represents a ApplicationInferenceProfile, either created with CDK or imported. + */ +export interface IApplicationInferenceProfile extends IResource { + /** + * The ARN of the application inference profile. + */ + readonly inferenceProfileArn: string; + /** + * The unique identifier of the inference profile. + */ + readonly inferenceProfileId: string; + /** + * The ID or Amazon Resource Name (ARN) of the inference profile. + */ + readonly inferenceProfileIdentifier: string; +} + +/** + * Abstract base class for a ApplicationInferenceProfile. + * Contains methods and attributes valid for ApplicationInferenceProfiles either created with CDK or imported. + */ +export abstract class ApplicationInferenceProfileBase extends Resource implements IApplicationInferenceProfile { + /** + * The ARN of the application inference profile. + */ + public abstract readonly inferenceProfileArn: string; + /** + * The unique identifier of the inference profile. + */ + public abstract readonly inferenceProfileId: string; + /** + * The ID or Amazon Resource Name (ARN) of the inference profile. + */ + public abstract readonly inferenceProfileIdentifier: string; +} + +/****************************************************************************** + * PROPS FOR NEW CONSTRUCT + *****************************************************************************/ +/** + * Properties for creating a ApplicationInferenceProfile. + */ export interface ApplicationInferenceProfileProps { /** * Description of the inference profile. @@ -35,37 +82,85 @@ export interface ApplicationInferenceProfileProps { * Usage and costs for requests made to the Regions in the inference profile will be tracked. */ readonly modelSource: string; + /** + * A list of tags associated with the inference profile. + * */ + readonly tags?: Array; +} + +/****************************************************************************** + * ATTRS FOR IMPORTED CONSTRUCT + *****************************************************************************/ +export interface ApplicationInferenceApplicationAttributes { + /** + * The ARN of the application inference profile. + */ + readonly inferenceProfileArn: string; + /** + * The unique identifier of the inference profile. + */ + readonly inferenceProfileId: string; + /** + * The ID or Amazon Resource Name (ARN) of the inference profile. + */ + readonly inferenceProfileIdentifier: string; } +/****************************************************************************** + * NEW CONSTRUCT DEFINITION + *****************************************************************************/ /** - * Creates an application inference profile. - * + * Class to create a ApplicationInferenceProfile with CDK. * These are inference profiles created by users (user defined). * This helps to track costs and model usage. * @resource AWS::Bedrock::ApplicationInferenceProfile * @see https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-create.html */ -export class ApplicationInferenceProfile extends Construct { +export class ApplicationInferenceProfile extends ApplicationInferenceProfileBase { + /** + * Import a ApplicationInferenceProfile given its attributes + */ + public static fromApplicationInferenceProfileAttributes( + scope: Construct, + id: string, + attrs: ApplicationInferenceApplicationAttributes, + ): IApplicationInferenceProfile { + class Import extends ApplicationInferenceProfileBase { + public readonly inferenceProfileArn = attrs.inferenceProfileArn; + public readonly inferenceProfileId = attrs.inferenceProfileId; + public readonly inferenceProfileIdentifier = attrs.inferenceProfileIdentifier; + } + + return new Import(scope, id); + } + /** + * Import a low-level L1 Cfn ApplicationInferenceProfile + */ + public static fromCfnApplicationInferenceProfile( + CfnApplicationInferenceProfile: bedrock.CfnApplicationInferenceProfile, + ): IApplicationInferenceProfile { + return new (class extends ApplicationInferenceProfileBase { + public readonly inferenceProfileArn = CfnApplicationInferenceProfile.attrInferenceProfileArn; + public readonly inferenceProfileId = CfnApplicationInferenceProfile.attrInferenceProfileId; + public readonly inferenceProfileIdentifier = CfnApplicationInferenceProfile.attrInferenceProfileIdentifier; + })(CfnApplicationInferenceProfile, '@FromCfnApplicationInferenceProfile'); + } /** * The ARN of the application inference profile. */ public readonly inferenceProfileArn: string; - /** - * The ARN of the application inference profile. + * The unique identifier of the inference profile. */ public readonly inferenceProfileId: string; - /** - * The unique identifier of the inference profile. + * The ID or Amazon Resource Name (ARN) of the inference profile. */ public readonly inferenceProfileIdentifier: string; - /** * The status of the inference profile. ACTIVE means that the inference profile is ready to be used. */ public readonly status: string; - /** * The type of the inference profile. The following types are possible: * SYSTEM_DEFINED – The inference profile is defined by Amazon Bedrock. @@ -75,7 +170,14 @@ export class ApplicationInferenceProfile extends Construct { * The inference profile may route requests to one or multiple regions. */ public readonly type: string; - + /** + * Time Stamp for ApplicationInferenceProfile creation. + */ + public readonly createdAt: string; + /** + * Time Stamp for ApplicationInferenceProfile update. + */ + public readonly updatedAt: string; /** * Instance of CfnApplicationInferenceProfile. */ @@ -91,13 +193,16 @@ export class ApplicationInferenceProfile extends Construct { modelSource: { copyFrom: props.modelSource, }, + tags: props.tags, }); + // build attributes this.inferenceProfileArn = this._resource.attrInferenceProfileArn; this.inferenceProfileId = this._resource.attrInferenceProfileId; this.inferenceProfileIdentifier = this._resource.attrInferenceProfileIdentifier; this.status = this._resource.attrStatus; this.type = this._resource.attrType; + this.createdAt = this._resource.attrCreatedAt; + this.updatedAt = this._resource.attrUpdatedAt; } - } \ No newline at end of file diff --git a/test/cdk-lib/bedrock/application-inference-profile.test.ts b/test/cdk-lib/bedrock/application-inference-profile.test.ts index 1b010a1e..e3c02abd 100644 --- a/test/cdk-lib/bedrock/application-inference-profile.test.ts +++ b/test/cdk-lib/bedrock/application-inference-profile.test.ts @@ -12,6 +12,7 @@ */ import * as cdk from 'aws-cdk-lib'; import { Match, Template } from 'aws-cdk-lib/assertions'; +import { CfnApplicationInferenceProfile } from 'aws-cdk-lib/aws-bedrock'; import { AwsSolutionsChecks } from 'cdk-nag'; import * as bedrock from '../../../src/cdk-lib/bedrock'; @@ -29,6 +30,12 @@ describe('CDK-Created-Application-Inference-Profile', () => { inferenceProfileName: 'TestAIP', description: 'This is a test application inf profile', modelSource: bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0.asArn(stack), + tags: [ + { + key: 'test-key', + value: 'test-value', + }, + ], }); Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::ApplicationInferenceProfile', { @@ -48,6 +55,12 @@ describe('CDK-Created-Application-Inference-Profile', () => { ], }, }, + Tags: [ + { + Key: 'test-key', + Value: 'test-value', + }, + ], }); }); @@ -66,3 +79,46 @@ describe('CDK-Created-Application-Inference-Profile', () => { }); }); }); + +describe('Imported-ApplicationInferenceProfile', () => { + let stack: cdk.Stack; + + beforeEach(() => { + const app = new cdk.App(); + cdk.Aspects.of(app).add(new AwsSolutionsChecks()); + stack = new cdk.Stack(app, 'TestStack2', { + env: { + account: '123456789012', + region: 'us-east-1', + }, + }); + }); + + test('Basic Import - from attributes', () => { + const aip = bedrock.ApplicationInferenceProfile.fromApplicationInferenceProfileAttributes(stack, 'TestAIP', { + inferenceProfileArn: 'arn:aws:bedrock:us-east-1:123456789012:application-inference-profile/cew2pa5r8hog', + inferenceProfileId: 'cew2pa5r8hog', + inferenceProfileIdentifier: 'arn:aws:bedrock:us-east-1:123456789012:application-inference-profile/cew2pa5r8hog', + }); + + expect(aip.inferenceProfileArn).toBe('arn:aws:bedrock:us-east-1:123456789012:application-inference-profile/cew2pa5r8hog'); + expect(aip.inferenceProfileId).toBe('cew2pa5r8hog'); + expect(aip.inferenceProfileIdentifier).toBe('arn:aws:bedrock:us-east-1:123456789012:application-inference-profile/cew2pa5r8hog'); + }); + + test('Basic Import - from cfn', () => { + + const cfnapp = new CfnApplicationInferenceProfile(stack, 'mytest', { + inferenceProfileName: 'mytest', + modelSource: { + copyFrom: 'arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0', + }, + }); + + const aip2 = bedrock.ApplicationInferenceProfile.fromCfnApplicationInferenceProfile(cfnapp); + + expect(aip2.inferenceProfileArn).toBe(cfnapp.attrInferenceProfileArn); + expect(aip2.inferenceProfileId).toBe(cfnapp.attrInferenceProfileId); + expect(aip2.inferenceProfileIdentifier).toBe(cfnapp.attrInferenceProfileIdentifier); + }); +}); From 241e1a7f0067b901d6de7a45897fd8a52d899284 Mon Sep 17 00:00:00 2001 From: krokoko Date: Wed, 13 Nov 2024 18:26:55 -0600 Subject: [PATCH 06/22] chore(aip): calculate id and expose name as attr --- .../bedrock/classes/ApplicationInferenceProfile.md | 8 ++++++++ .../ApplicationInferenceApplicationAttributes.md | 8 -------- src/cdk-lib/bedrock/README.md | 2 -- .../bedrock/application-inference-profile.ts | 14 ++++++++------ .../bedrock/application-inference-profile.test.ts | 1 - 5 files changed, 16 insertions(+), 17 deletions(-) diff --git a/apidocs/namespaces/bedrock/classes/ApplicationInferenceProfile.md b/apidocs/namespaces/bedrock/classes/ApplicationInferenceProfile.md index 5d3cb454..bc9489ab 100644 --- a/apidocs/namespaces/bedrock/classes/ApplicationInferenceProfile.md +++ b/apidocs/namespaces/bedrock/classes/ApplicationInferenceProfile.md @@ -108,6 +108,14 @@ The ID or Amazon Resource Name (ARN) of the inference profile. *** +### inferenceProfileName + +> `readonly` **inferenceProfileName**: `string` + +The name of the application inference profile. + +*** + ### node > `readonly` **node**: `Node` diff --git a/apidocs/namespaces/bedrock/interfaces/ApplicationInferenceApplicationAttributes.md b/apidocs/namespaces/bedrock/interfaces/ApplicationInferenceApplicationAttributes.md index 1bb986b8..88f5fc90 100644 --- a/apidocs/namespaces/bedrock/interfaces/ApplicationInferenceApplicationAttributes.md +++ b/apidocs/namespaces/bedrock/interfaces/ApplicationInferenceApplicationAttributes.md @@ -20,14 +20,6 @@ The ARN of the application inference profile. *** -### inferenceProfileId - -> `readonly` **inferenceProfileId**: `string` - -The unique identifier of the inference profile. - -*** - ### inferenceProfileIdentifier > `readonly` **inferenceProfileIdentifier**: `string` diff --git a/src/cdk-lib/bedrock/README.md b/src/cdk-lib/bedrock/README.md index 278302ab..92b03dc1 100644 --- a/src/cdk-lib/bedrock/README.md +++ b/src/cdk-lib/bedrock/README.md @@ -1359,7 +1359,6 @@ const appInfProfile3 = bedrock.ApplicationInferenceProfile.fromCfnApplicationInf // Import an inference profile through attributes const appInfProfile4 = bedrock.ApplicationInferenceProfile.fromApplicationInferenceProfileAttributes(this, 'TestAIP', { inferenceProfileArn: 'arn:aws:bedrock:us-east-1:XXXXX:application-inference-profile/ID', - inferenceProfileId: 'ID', inferenceProfileIdentifier: 'arn:aws:bedrock:us-east-1:XXXXXXX:application-inference-profile/ID', }); @@ -1389,7 +1388,6 @@ appInfProfile2 = bedrock.ApplicationInferenceProfile(self, 'myapplicationprofile # Import an inference profile through attributes appInfProfile3 = bedrock.ApplicationInferenceProfile.from_application_inference_profile_attributes(self, 'TestAIP', inference_profile_arn='arn:aws:bedrock:us-east-1:XXXXX:application-inference-profile/ID', - inference_profile_id='ID', inference_profile_identifier='arn:aws:bedrock:us-east-1:XXXXXXX:application-inference-profile/ID', ) diff --git a/src/cdk-lib/bedrock/application-inference-profile.ts b/src/cdk-lib/bedrock/application-inference-profile.ts index a1c86d77..44592735 100644 --- a/src/cdk-lib/bedrock/application-inference-profile.ts +++ b/src/cdk-lib/bedrock/application-inference-profile.ts @@ -10,7 +10,7 @@ * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions * and limitations under the License. */ -import { IResource, Resource, CfnTag } from 'aws-cdk-lib'; +import { IResource, Resource, CfnTag, Arn, ArnFormat } from 'aws-cdk-lib'; import * as bedrock from 'aws-cdk-lib/aws-bedrock'; import { Construct } from 'constructs'; @@ -96,10 +96,6 @@ export interface ApplicationInferenceApplicationAttributes { * The ARN of the application inference profile. */ readonly inferenceProfileArn: string; - /** - * The unique identifier of the inference profile. - */ - readonly inferenceProfileId: string; /** * The ID or Amazon Resource Name (ARN) of the inference profile. */ @@ -127,7 +123,7 @@ export class ApplicationInferenceProfile extends ApplicationInferenceProfileBase ): IApplicationInferenceProfile { class Import extends ApplicationInferenceProfileBase { public readonly inferenceProfileArn = attrs.inferenceProfileArn; - public readonly inferenceProfileId = attrs.inferenceProfileId; + public readonly inferenceProfileId = Arn.split(attrs.inferenceProfileArn, ArnFormat.SLASH_RESOURCE_NAME).resourceName!;; public readonly inferenceProfileIdentifier = attrs.inferenceProfileIdentifier; } @@ -145,6 +141,10 @@ export class ApplicationInferenceProfile extends ApplicationInferenceProfileBase public readonly inferenceProfileIdentifier = CfnApplicationInferenceProfile.attrInferenceProfileIdentifier; })(CfnApplicationInferenceProfile, '@FromCfnApplicationInferenceProfile'); } + /** + * The name of the application inference profile. + */ + public readonly inferenceProfileName: string; /** * The ARN of the application inference profile. */ @@ -186,6 +186,8 @@ export class ApplicationInferenceProfile extends ApplicationInferenceProfileBase constructor(scope: Construct, id: string, props: ApplicationInferenceProfileProps) { super(scope, id); + this.inferenceProfileName = props.inferenceProfileName; + // L1 instantiation this._resource = new bedrock.CfnApplicationInferenceProfile(this, id, { description: props.description, diff --git a/test/cdk-lib/bedrock/application-inference-profile.test.ts b/test/cdk-lib/bedrock/application-inference-profile.test.ts index e3c02abd..bcb079db 100644 --- a/test/cdk-lib/bedrock/application-inference-profile.test.ts +++ b/test/cdk-lib/bedrock/application-inference-profile.test.ts @@ -97,7 +97,6 @@ describe('Imported-ApplicationInferenceProfile', () => { test('Basic Import - from attributes', () => { const aip = bedrock.ApplicationInferenceProfile.fromApplicationInferenceProfileAttributes(stack, 'TestAIP', { inferenceProfileArn: 'arn:aws:bedrock:us-east-1:123456789012:application-inference-profile/cew2pa5r8hog', - inferenceProfileId: 'cew2pa5r8hog', inferenceProfileIdentifier: 'arn:aws:bedrock:us-east-1:123456789012:application-inference-profile/cew2pa5r8hog', }); From 8038ce00faab08fc6a101279446ae7915f3823b4 Mon Sep 17 00:00:00 2001 From: krokoko Date: Wed, 13 Nov 2024 18:53:29 -0600 Subject: [PATCH 07/22] chore(aip): update attributes interface name --- apidocs/namespaces/bedrock/README.md | 2 +- .../namespaces/bedrock/classes/ApplicationInferenceProfile.md | 2 +- ...Attributes.md => ApplicationInferenceProfileAttributes.md} | 4 ++-- src/cdk-lib/bedrock/application-inference-profile.ts | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) rename apidocs/namespaces/bedrock/interfaces/{ApplicationInferenceApplicationAttributes.md => ApplicationInferenceProfileAttributes.md} (84%) diff --git a/apidocs/namespaces/bedrock/README.md b/apidocs/namespaces/bedrock/README.md index 7c663090..c00bc4ea 100644 --- a/apidocs/namespaces/bedrock/README.md +++ b/apidocs/namespaces/bedrock/README.md @@ -74,7 +74,7 @@ - [AgentAliasProps](interfaces/AgentAliasProps.md) - [AgentProps](interfaces/AgentProps.md) - [ApiSchemaConfig](interfaces/ApiSchemaConfig.md) -- [ApplicationInferenceApplicationAttributes](interfaces/ApplicationInferenceApplicationAttributes.md) +- [ApplicationInferenceProfileAttributes](interfaces/ApplicationInferenceProfileAttributes.md) - [ApplicationInferenceProfileProps](interfaces/ApplicationInferenceProfileProps.md) - [BedrockFoundationModelProps](interfaces/BedrockFoundationModelProps.md) - [CommonPromptVariantProps](interfaces/CommonPromptVariantProps.md) diff --git a/apidocs/namespaces/bedrock/classes/ApplicationInferenceProfile.md b/apidocs/namespaces/bedrock/classes/ApplicationInferenceProfile.md index bc9489ab..2dd14d20 100644 --- a/apidocs/namespaces/bedrock/classes/ApplicationInferenceProfile.md +++ b/apidocs/namespaces/bedrock/classes/ApplicationInferenceProfile.md @@ -343,7 +343,7 @@ Import a ApplicationInferenceProfile given its attributes • **id**: `string` -• **attrs**: [`ApplicationInferenceApplicationAttributes`](../interfaces/ApplicationInferenceApplicationAttributes.md) +• **attrs**: [`ApplicationInferenceProfileAttributes`](../interfaces/ApplicationInferenceProfileAttributes.md) #### Returns diff --git a/apidocs/namespaces/bedrock/interfaces/ApplicationInferenceApplicationAttributes.md b/apidocs/namespaces/bedrock/interfaces/ApplicationInferenceProfileAttributes.md similarity index 84% rename from apidocs/namespaces/bedrock/interfaces/ApplicationInferenceApplicationAttributes.md rename to apidocs/namespaces/bedrock/interfaces/ApplicationInferenceProfileAttributes.md index 88f5fc90..12924b93 100644 --- a/apidocs/namespaces/bedrock/interfaces/ApplicationInferenceApplicationAttributes.md +++ b/apidocs/namespaces/bedrock/interfaces/ApplicationInferenceProfileAttributes.md @@ -2,9 +2,9 @@ *** -[@cdklabs/generative-ai-cdk-constructs](../../../README.md) / [bedrock](../README.md) / ApplicationInferenceApplicationAttributes +[@cdklabs/generative-ai-cdk-constructs](../../../README.md) / [bedrock](../README.md) / ApplicationInferenceProfileAttributes -# Interface: ApplicationInferenceApplicationAttributes +# Interface: ApplicationInferenceProfileAttributes *************************************************************************** ATTRS FOR IMPORTED CONSTRUCT diff --git a/src/cdk-lib/bedrock/application-inference-profile.ts b/src/cdk-lib/bedrock/application-inference-profile.ts index 44592735..53f32dff 100644 --- a/src/cdk-lib/bedrock/application-inference-profile.ts +++ b/src/cdk-lib/bedrock/application-inference-profile.ts @@ -91,7 +91,7 @@ export interface ApplicationInferenceProfileProps { /****************************************************************************** * ATTRS FOR IMPORTED CONSTRUCT *****************************************************************************/ -export interface ApplicationInferenceApplicationAttributes { +export interface ApplicationInferenceProfileAttributes { /** * The ARN of the application inference profile. */ @@ -119,7 +119,7 @@ export class ApplicationInferenceProfile extends ApplicationInferenceProfileBase public static fromApplicationInferenceProfileAttributes( scope: Construct, id: string, - attrs: ApplicationInferenceApplicationAttributes, + attrs: ApplicationInferenceProfileAttributes, ): IApplicationInferenceProfile { class Import extends ApplicationInferenceProfileBase { public readonly inferenceProfileArn = attrs.inferenceProfileArn; From 96876caa79bce369523e006688ff11d83e186bc0 Mon Sep 17 00:00:00 2001 From: krokoko Date: Fri, 15 Nov 2024 10:17:43 -0600 Subject: [PATCH 08/22] chore(deps): upgrade to cdk 2.167 --- .projen/deps.json | 4 ++-- .projenrc.ts | 2 +- CHANGELOG.md | 4 ++-- DEVELOPER_GUIDE.md | 2 +- apidocs/interfaces/DockerLambdaCustomProps.md | 2 +- package.json | 6 +++--- src/common/props/DockerLambdaCustomProps.ts | 2 +- yarn.lock | 16 ++++++++-------- 8 files changed, 19 insertions(+), 19 deletions(-) diff --git a/.projen/deps.json b/.projen/deps.json index f367a4fe..5a108f67 100644 --- a/.projen/deps.json +++ b/.projen/deps.json @@ -6,7 +6,7 @@ }, { "name": "@aws-cdk/integ-tests-alpha", - "version": "2.166.0-alpha.0", + "version": "2.167.0-alpha.0", "type": "build" }, { @@ -137,7 +137,7 @@ }, { "name": "aws-cdk-lib", - "version": "^2.166.0", + "version": "^2.167.0", "type": "peer" }, { diff --git a/.projenrc.ts b/.projenrc.ts index 29a33cc8..93b5ad6e 100644 --- a/.projenrc.ts +++ b/.projenrc.ts @@ -30,7 +30,7 @@ import { const GITHUB_USER = 'awslabs'; const PUBLICATION_NAMESPACE = 'cdklabs'; const PROJECT_NAME = 'generative-ai-cdk-constructs'; -const CDK_VERSION: string = '2.166.0'; +const CDK_VERSION: string = '2.167.0'; function camelCaseIt(input: string): string { // Hypens and dashes to spaces and then CamelCase... diff --git a/CHANGELOG.md b/CHANGELOG.md index ab8857c3..f563868d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ -# CDK Generative AI Constructs V0.1.281 (2024-11-15) +# CDK Generative AI Constructs V0.1.282 (2024-11-18) -Based on CDK library version 2.166.0 +Based on CDK library version 2.167.0 # CDK Generative AI Constructs V0.1.273 (2024-10-15) diff --git a/DEVELOPER_GUIDE.md b/DEVELOPER_GUIDE.md index 9118b64b..38f66a84 100644 --- a/DEVELOPER_GUIDE.md +++ b/DEVELOPER_GUIDE.md @@ -16,7 +16,7 @@ Default output format [None]: json ``` - [Node](https://nodejs.org/en) >= v20.9.0 -- [AWS CDK](https://github.com/aws/aws-cdk/releases/tag/v2.166.0) >= 2.166.0 +- [AWS CDK](https://github.com/aws/aws-cdk/releases/tag/v2.167.0) >= 2.167.0 - [Python](https://www.python.org/downloads/) >=3.9 - [Projen](https://github.com/projen/projen) >= 0.78.8 - [Yarn](https://classic.yarnpkg.com/lang/en/docs/cli/install/) >= 1.22.19 diff --git a/apidocs/interfaces/DockerLambdaCustomProps.md b/apidocs/interfaces/DockerLambdaCustomProps.md index 51aa9785..21a1f797 100644 --- a/apidocs/interfaces/DockerLambdaCustomProps.md +++ b/apidocs/interfaces/DockerLambdaCustomProps.md @@ -669,7 +669,7 @@ stable > `readonly` `optional` **snapStart**: `SnapStartConf` Enable SnapStart for Lambda Function. -SnapStart is currently supported only for Java 11, 17 runtime +SnapStart is currently supported for Java 11, Java 17, Python 3.12, Python 3.13, and .NET 8 runtime #### Default diff --git a/package.json b/package.json index 8f6cedb7..4f5486f6 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ }, "devDependencies": { "@aws-cdk/assert": "^2.68.0", - "@aws-cdk/integ-tests-alpha": "2.166.0-alpha.0", + "@aws-cdk/integ-tests-alpha": "2.167.0-alpha.0", "@commitlint/config-conventional": "^18.6.3", "@mrgrain/jsii-struct-builder": "^0.7.43", "@types/jest": "^29.5.14", @@ -63,7 +63,7 @@ "@typescript-eslint/eslint-plugin": "^7", "@typescript-eslint/parser": "^7", "aws-cdk": "^2", - "aws-cdk-lib": "2.166.0", + "aws-cdk-lib": "2.167.0", "aws-sdk-mock": "^5.9.0", "commitlint": "^18.6.1", "constructs": "10.3.0", @@ -88,7 +88,7 @@ "typescript": "^5.6.3" }, "peerDependencies": { - "aws-cdk-lib": "^2.166.0", + "aws-cdk-lib": "^2.167.0", "constructs": "^10.3.0" }, "dependencies": { diff --git a/src/common/props/DockerLambdaCustomProps.ts b/src/common/props/DockerLambdaCustomProps.ts index 2523169a..2f691ac8 100644 --- a/src/common/props/DockerLambdaCustomProps.ts +++ b/src/common/props/DockerLambdaCustomProps.ts @@ -29,7 +29,7 @@ export interface DockerLambdaCustomProps { readonly systemLogLevelV2?: aws_lambda.SystemLogLevel; /** * Enable SnapStart for Lambda Function. - * SnapStart is currently supported only for Java 11, 17 runtime + * SnapStart is currently supported for Java 11, Java 17, Python 3.12, Python 3.13, and .NET 8 runtime * @default - No snapstart * @stability stable */ diff --git a/yarn.lock b/yarn.lock index ed9b618f..ecee8063 100644 --- a/yarn.lock +++ b/yarn.lock @@ -60,10 +60,10 @@ string-width "^4.2.3" table "^6.8.1" -"@aws-cdk/integ-tests-alpha@2.166.0-alpha.0": - version "2.166.0-alpha.0" - resolved "https://registry.yarnpkg.com/@aws-cdk/integ-tests-alpha/-/integ-tests-alpha-2.166.0-alpha.0.tgz#fc82a90c422cd0ff90ee4b3f72026b6eb900cd1b" - integrity sha512-ksM64XQP0FzzGxmVFQQDF8JIJKJpcfUoFWTvRghDMDNq8IBi/KsP4/gXpHDyl4jtS58EPOMBpsy0SRCFyOCVvw== +"@aws-cdk/integ-tests-alpha@2.167.0-alpha.0": + version "2.167.0-alpha.0" + resolved "https://registry.yarnpkg.com/@aws-cdk/integ-tests-alpha/-/integ-tests-alpha-2.167.0-alpha.0.tgz#a8d3dc8d2bdb5900fd713d13c49a28d3d8e2556b" + integrity sha512-3C3T/ZeJouGZYIAxhMI1DIx6aQlbb6Vid+nYouyEtFjHl0dQnsmZU7XLAsUdtUZxl2+HuDjkuG9Akf3o1iDC0Q== "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.25.9", "@babel/code-frame@^7.26.0": version "7.26.2" @@ -1428,10 +1428,10 @@ available-typed-arrays@^1.0.7: dependencies: possible-typed-array-names "^1.0.0" -aws-cdk-lib@2.166.0: - version "2.166.0" - resolved "https://registry.yarnpkg.com/aws-cdk-lib/-/aws-cdk-lib-2.166.0.tgz#279343451cc9391d52d77121e2a3feb2c756e3be" - integrity sha512-FAsIz/CpczbMrcShgvTWNp3kcGN6IDojJWNLqHioTRsTekcyN3OPmKvQJXUNWL0fnhTd8biFXC2esg6kM19xZw== +aws-cdk-lib@2.167.0: + version "2.167.0" + resolved "https://registry.yarnpkg.com/aws-cdk-lib/-/aws-cdk-lib-2.167.0.tgz#7f2a8534a5054155e3a03f9d695ef5b8a60c14a8" + integrity sha512-q8bHxUUnMGfHe4TWQHYUu4eqdy9qkEWuml3vOnZINF3l9XdKOo/S5grsyVzFAjjBjwCH8zAxKicNT0uhwBjqLg== dependencies: "@aws-cdk/asset-awscli-v1" "^2.2.208" "@aws-cdk/asset-kubectl-v20" "^2.1.3" From 212521e80b4c483d5551c9e392c88b7d4808789e Mon Sep 17 00:00:00 2001 From: Rafael Mosca Date: Fri, 15 Nov 2024 17:57:12 +0100 Subject: [PATCH 09/22] feat(bedrock): add cross-region inference profiles --- .../bedrock/application-inference-profile.ts | 210 ------------------ src/cdk-lib/bedrock/index.ts | 42 ++-- .../application-inference-profile.ts | 168 ++++++++++++++ .../bedrock/inference-profiles/common.ts | 88 ++++++++ .../cross-region-inference-profile.ts | 79 +++++++ src/cdk-lib/bedrock/models.ts | 185 +++++++++------ .../application-inference-profile.test.ts | 123 ---------- .../cdk-lib/bedrock/inference-profile.test.ts | 117 ++++++++++ 8 files changed, 594 insertions(+), 418 deletions(-) delete mode 100644 src/cdk-lib/bedrock/application-inference-profile.ts create mode 100644 src/cdk-lib/bedrock/inference-profiles/application-inference-profile.ts create mode 100644 src/cdk-lib/bedrock/inference-profiles/common.ts create mode 100644 src/cdk-lib/bedrock/inference-profiles/cross-region-inference-profile.ts delete mode 100644 test/cdk-lib/bedrock/application-inference-profile.test.ts create mode 100644 test/cdk-lib/bedrock/inference-profile.test.ts diff --git a/src/cdk-lib/bedrock/application-inference-profile.ts b/src/cdk-lib/bedrock/application-inference-profile.ts deleted file mode 100644 index 53f32dff..00000000 --- a/src/cdk-lib/bedrock/application-inference-profile.ts +++ /dev/null @@ -1,210 +0,0 @@ -/** - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance - * with the License. A copy of the License is located at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES - * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions - * and limitations under the License. - */ -import { IResource, Resource, CfnTag, Arn, ArnFormat } from 'aws-cdk-lib'; -import * as bedrock from 'aws-cdk-lib/aws-bedrock'; -import { Construct } from 'constructs'; - -/****************************************************************************** - * COMMON - *****************************************************************************/ -/** - * Represents a ApplicationInferenceProfile, either created with CDK or imported. - */ -export interface IApplicationInferenceProfile extends IResource { - /** - * The ARN of the application inference profile. - */ - readonly inferenceProfileArn: string; - /** - * The unique identifier of the inference profile. - */ - readonly inferenceProfileId: string; - /** - * The ID or Amazon Resource Name (ARN) of the inference profile. - */ - readonly inferenceProfileIdentifier: string; -} - -/** - * Abstract base class for a ApplicationInferenceProfile. - * Contains methods and attributes valid for ApplicationInferenceProfiles either created with CDK or imported. - */ -export abstract class ApplicationInferenceProfileBase extends Resource implements IApplicationInferenceProfile { - /** - * The ARN of the application inference profile. - */ - public abstract readonly inferenceProfileArn: string; - /** - * The unique identifier of the inference profile. - */ - public abstract readonly inferenceProfileId: string; - /** - * The ID or Amazon Resource Name (ARN) of the inference profile. - */ - public abstract readonly inferenceProfileIdentifier: string; -} - -/****************************************************************************** - * PROPS FOR NEW CONSTRUCT - *****************************************************************************/ -/** - * Properties for creating a ApplicationInferenceProfile. - */ -export interface ApplicationInferenceProfileProps { - /** - * Description of the inference profile. - * @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-bedrock-applicationinferenceprofile.html#cfn-bedrock-applicationinferenceprofile-description - */ - readonly description?: string; - /** - * The name of the inference profile. - * @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-bedrock-applicationinferenceprofile.html#cfn-bedrock-applicationinferenceprofile-inferenceprofilename - */ - readonly inferenceProfileName: string; - /** - * To create an application inference profile for one Region, specify a foundation model. - * Usage and costs for requests made to that Region with that model will be tracked. - * - * To create an application inference profile for multiple Regions, - * specify a cross region (system-defined) inference profile. - * The inference profile will route requests to the Regions defined in - * the cross region (system-defined) inference profile that you choose. - * Usage and costs for requests made to the Regions in the inference profile will be tracked. - */ - readonly modelSource: string; - /** - * A list of tags associated with the inference profile. - * */ - readonly tags?: Array; -} - -/****************************************************************************** - * ATTRS FOR IMPORTED CONSTRUCT - *****************************************************************************/ -export interface ApplicationInferenceProfileAttributes { - /** - * The ARN of the application inference profile. - */ - readonly inferenceProfileArn: string; - /** - * The ID or Amazon Resource Name (ARN) of the inference profile. - */ - readonly inferenceProfileIdentifier: string; -} - -/****************************************************************************** - * NEW CONSTRUCT DEFINITION - *****************************************************************************/ -/** - * Class to create a ApplicationInferenceProfile with CDK. - * These are inference profiles created by users (user defined). - * This helps to track costs and model usage. - * @resource AWS::Bedrock::ApplicationInferenceProfile - * @see https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-create.html - */ -export class ApplicationInferenceProfile extends ApplicationInferenceProfileBase { - /** - * Import a ApplicationInferenceProfile given its attributes - */ - public static fromApplicationInferenceProfileAttributes( - scope: Construct, - id: string, - attrs: ApplicationInferenceProfileAttributes, - ): IApplicationInferenceProfile { - class Import extends ApplicationInferenceProfileBase { - public readonly inferenceProfileArn = attrs.inferenceProfileArn; - public readonly inferenceProfileId = Arn.split(attrs.inferenceProfileArn, ArnFormat.SLASH_RESOURCE_NAME).resourceName!;; - public readonly inferenceProfileIdentifier = attrs.inferenceProfileIdentifier; - } - - return new Import(scope, id); - } - /** - * Import a low-level L1 Cfn ApplicationInferenceProfile - */ - public static fromCfnApplicationInferenceProfile( - CfnApplicationInferenceProfile: bedrock.CfnApplicationInferenceProfile, - ): IApplicationInferenceProfile { - return new (class extends ApplicationInferenceProfileBase { - public readonly inferenceProfileArn = CfnApplicationInferenceProfile.attrInferenceProfileArn; - public readonly inferenceProfileId = CfnApplicationInferenceProfile.attrInferenceProfileId; - public readonly inferenceProfileIdentifier = CfnApplicationInferenceProfile.attrInferenceProfileIdentifier; - })(CfnApplicationInferenceProfile, '@FromCfnApplicationInferenceProfile'); - } - /** - * The name of the application inference profile. - */ - public readonly inferenceProfileName: string; - /** - * The ARN of the application inference profile. - */ - public readonly inferenceProfileArn: string; - /** - * The unique identifier of the inference profile. - */ - public readonly inferenceProfileId: string; - /** - * The ID or Amazon Resource Name (ARN) of the inference profile. - */ - public readonly inferenceProfileIdentifier: string; - /** - * The status of the inference profile. ACTIVE means that the inference profile is ready to be used. - */ - public readonly status: string; - /** - * The type of the inference profile. The following types are possible: - * SYSTEM_DEFINED – The inference profile is defined by Amazon Bedrock. - * You can route inference requests across regions with these inference profiles. - * APPLICATION – The inference profile was created by a user. - * This type of inference profile can track metrics and costs when invoking the model in it. - * The inference profile may route requests to one or multiple regions. - */ - public readonly type: string; - /** - * Time Stamp for ApplicationInferenceProfile creation. - */ - public readonly createdAt: string; - /** - * Time Stamp for ApplicationInferenceProfile update. - */ - public readonly updatedAt: string; - /** - * Instance of CfnApplicationInferenceProfile. - */ - private readonly _resource: bedrock.CfnApplicationInferenceProfile; - - constructor(scope: Construct, id: string, props: ApplicationInferenceProfileProps) { - super(scope, id); - - this.inferenceProfileName = props.inferenceProfileName; - - // L1 instantiation - this._resource = new bedrock.CfnApplicationInferenceProfile(this, id, { - description: props.description, - inferenceProfileName: props.inferenceProfileName, - modelSource: { - copyFrom: props.modelSource, - }, - tags: props.tags, - }); - - // build attributes - this.inferenceProfileArn = this._resource.attrInferenceProfileArn; - this.inferenceProfileId = this._resource.attrInferenceProfileId; - this.inferenceProfileIdentifier = this._resource.attrInferenceProfileIdentifier; - this.status = this._resource.attrStatus; - this.type = this._resource.attrType; - this.createdAt = this._resource.attrCreatedAt; - this.updatedAt = this._resource.attrUpdatedAt; - } -} \ No newline at end of file diff --git a/src/cdk-lib/bedrock/index.ts b/src/cdk-lib/bedrock/index.ts index 02778fef..890ee733 100644 --- a/src/cdk-lib/bedrock/index.ts +++ b/src/cdk-lib/bedrock/index.ts @@ -11,23 +11,25 @@ * and limitations under the License. */ -export * from './knowledge-base'; -export * from './agent'; -export * from './agent-alias'; -export * from './agent-action-group'; -export * from './api-schema'; -export * from './guardrails/guardrail-filters'; -export * from './guardrails/guardrails'; -export * from './models'; -export * from './prompts/prompt'; -export * from './prompts/prompt-version'; -export * from './data-sources/base-data-source'; -export * from './data-sources/chunking'; -export * from './data-sources/parsing'; -export * from './data-sources/custom-transformation'; -export * from './data-sources/web-crawler-data-source'; -export * from './data-sources/sharepoint-data-source'; -export * from './data-sources/confluence-data-source'; -export * from './data-sources/salesforce-data-source'; -export * from './data-sources/s3-data-source'; -export * from './application-inference-profile'; +export * from "./knowledge-base"; +export * from "./agent"; +export * from "./agent-alias"; +export * from "./agent-action-group"; +export * from "./api-schema"; +export * from "./guardrails/guardrail-filters"; +export * from "./guardrails/guardrails"; +export * from "./models"; +export * from "./prompts/prompt"; +export * from "./prompts/prompt-version"; +export * from "./data-sources/base-data-source"; +export * from "./data-sources/chunking"; +export * from "./data-sources/parsing"; +export * from "./data-sources/custom-transformation"; +export * from "./data-sources/web-crawler-data-source"; +export * from "./data-sources/sharepoint-data-source"; +export * from "./data-sources/confluence-data-source"; +export * from "./data-sources/salesforce-data-source"; +export * from "./data-sources/s3-data-source"; +export * from "./inference-profiles/application-inference-profile"; +export * from "./inference-profiles/common"; +export * from "./inference-profiles/cross-region-inference-profile"; diff --git a/src/cdk-lib/bedrock/inference-profiles/application-inference-profile.ts b/src/cdk-lib/bedrock/inference-profiles/application-inference-profile.ts new file mode 100644 index 00000000..cbaf629b --- /dev/null +++ b/src/cdk-lib/bedrock/inference-profiles/application-inference-profile.ts @@ -0,0 +1,168 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance + * with the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES + * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ +import { CfnTag, Arn, ArnFormat, Tag } from "aws-cdk-lib"; +import * as bedrock from "aws-cdk-lib/aws-bedrock"; +import { Construct } from "constructs"; +import { IInferenceProfile, InferenceProfileBase, InferenceProfileType } from "./common"; + +/****************************************************************************** + * PROPS FOR NEW CONSTRUCT + *****************************************************************************/ +/** + * Properties for creating a ApplicationInferenceProfile. + */ +export interface ApplicationInferenceProfileProps { + /** + * Description of the inference profile. + * @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-bedrock-applicationinferenceprofile.html#cfn-bedrock-applicationinferenceprofile-description + */ + readonly description?: string; + /** + * The name of the inference profile. + * @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-bedrock-applicationinferenceprofile.html#cfn-bedrock-applicationinferenceprofile-inferenceprofilename + */ + readonly inferenceProfileName: string; + /** + * To create an application inference profile for one Region, specify a foundation model. + * Usage and costs for requests made to that Region with that model will be tracked. + * + * To create an application inference profile for multiple Regions, + * specify a cross region (system-defined) inference profile. + * The inference profile will route requests to the Regions defined in + * the cross region (system-defined) inference profile that you choose. + * Usage and costs for requests made to the Regions in the inference profile will be tracked. + */ + readonly modelSource: bedrock.IModel; + /** + * A list of tags associated with the inference profile. + * */ + readonly tags?: Array; +} + +/****************************************************************************** + * ATTRS FOR IMPORTED CONSTRUCT + *****************************************************************************/ +export interface ApplicationInferenceProfileAttributes { + /** + * The ARN of the application inference profile. + */ + readonly inferenceProfileArn: string; + /** + * The ID or Amazon Resource Name (ARN) of the inference profile. + */ + readonly inferenceProfileIdentifier: string; +} + +/****************************************************************************** + * NEW CONSTRUCT DEFINITION + *****************************************************************************/ +/** + * Class to create a ApplicationInferenceProfile with CDK. + * These are inference profiles created by users (user defined). + * This helps to track costs and model usage. + * @resource AWS::Bedrock::ApplicationInferenceProfile + * @see https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-create.html + */ +export class ApplicationInferenceProfile extends InferenceProfileBase { + /** + * Import a ApplicationInferenceProfile given its attributes + */ + public static fromApplicationInferenceProfileAttributes( + scope: Construct, + id: string, + attrs: ApplicationInferenceProfileAttributes + ): IInferenceProfile { + class Import extends InferenceProfileBase { + public readonly inferenceProfileArn = attrs.inferenceProfileArn; + public readonly inferenceProfileId = Arn.split(attrs.inferenceProfileArn, ArnFormat.SLASH_RESOURCE_NAME) + .resourceName!; + public readonly type = InferenceProfileType.APPLICATION; + } + + return new Import(scope, id); + } + /** + * Import a low-level L1 Cfn ApplicationInferenceProfile + */ + public static fromCfnApplicationInferenceProfile( + CfnApplicationInferenceProfile: bedrock.CfnApplicationInferenceProfile + ): IInferenceProfile { + return new (class extends InferenceProfileBase { + public readonly inferenceProfileArn = CfnApplicationInferenceProfile.attrInferenceProfileArn; + public readonly inferenceProfileId = CfnApplicationInferenceProfile.attrInferenceProfileId; + public readonly type = InferenceProfileType.APPLICATION; + })(CfnApplicationInferenceProfile, "@FromCfnApplicationInferenceProfile"); + } + /** + * The name of the application inference profile. + */ + public readonly inferenceProfileName: string; + /** + * The ARN of the application inference profile. + */ + public readonly inferenceProfileArn: string; + /** + * The unique identifier of the inference profile. + */ + public readonly inferenceProfileId: string; + /** + * The status of the inference profile. ACTIVE means that the inference profile is ready to be used. + */ + public readonly status: string; + /** + * The type of the inference profile. The following types are possible: + * SYSTEM_DEFINED – The inference profile is defined by Amazon Bedrock. + * You can route inference requests across regions with these inference profiles. + * APPLICATION – The inference profile was created by a user. + * This type of inference profile can track metrics and costs when invoking the model in it. + * The inference profile may route requests to one or multiple regions. + */ + public readonly type: InferenceProfileType; + /** + * Time Stamp for ApplicationInferenceProfile creation. + */ + public readonly createdAt: string; + /** + * Time Stamp for ApplicationInferenceProfile update. + */ + public readonly updatedAt: string; + /** + * Instance of CfnApplicationInferenceProfile. + */ + private readonly _resource: bedrock.CfnApplicationInferenceProfile; + + constructor(scope: Construct, id: string, props: ApplicationInferenceProfileProps) { + super(scope, id); + + this.inferenceProfileName = props.inferenceProfileName; + this.type = InferenceProfileType.APPLICATION; + + // L1 instantiation + this._resource = new bedrock.CfnApplicationInferenceProfile(this, id, { + description: props.description, + inferenceProfileName: props.inferenceProfileName, + modelSource: { + copyFrom: props.modelSource.modelArn, + }, + tags: props.tags, + }); + + // build attributes + this.inferenceProfileArn = this._resource.attrInferenceProfileArn; + this.inferenceProfileId = this._resource.attrInferenceProfileId; + this.status = this._resource.attrStatus; + this.type = this._resource.attrType as InferenceProfileType; + this.createdAt = this._resource.attrCreatedAt; + this.updatedAt = this._resource.attrUpdatedAt; + } +} diff --git a/src/cdk-lib/bedrock/inference-profiles/common.ts b/src/cdk-lib/bedrock/inference-profiles/common.ts new file mode 100644 index 00000000..52fc487f --- /dev/null +++ b/src/cdk-lib/bedrock/inference-profiles/common.ts @@ -0,0 +1,88 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance + * with the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES + * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ +import { IResource, Resource } from "aws-cdk-lib"; +import { IModel } from "aws-cdk-lib/aws-bedrock"; +import { Grant, IGrantable } from "aws-cdk-lib/aws-iam"; + +/** These are the values used by the API when using aws bedrock get-inference-profile --inference-profile-identifier XXXXXXX */ +export enum InferenceProfileType { + /** + * An inference profile that is created by AWS. These are profiles such as cross-region + * which help you distributed traffic across a geographic region. + */ + SYSTEM_DEFINED = "SYSTEM_DEFINED", + /** + * An inference profile that is user-created. These are profiles that help + * you track costs or metrics. + */ + APPLICATION = "APPLICATION", +} + +/****************************************************************************** + * COMMON + *****************************************************************************/ +/** + * Represents a ApplicationInferenceProfile, either created with CDK or imported. + */ +export interface IInferenceProfile extends IResource { + /** + * The ARN of the application inference profile. + */ + readonly inferenceProfileArn: string; + /** + * The unique identifier of the inference profile. + */ + readonly inferenceProfileId: string; + /** + * The type of inference profile. + */ + readonly type: InferenceProfileType; + + /** + * Grants appropriate permissions to use the inference profile. + */ + grantProfileUsage(grantee: IGrantable): Grant; +} + +/** + * Abstract base class for a ApplicationInferenceProfile. + * Contains methods and attributes valid for ApplicationInferenceProfiles either created with CDK or imported. + */ +export abstract class InferenceProfileBase extends Resource implements IInferenceProfile { + /** + * The ARN of the application inference profile. + */ + public abstract readonly inferenceProfileArn: string; + /** + * The unique identifier of the inference profile. + */ + public abstract readonly inferenceProfileId: string; + /** + * The ID or Amazon Resource Name (ARN) of the inference profile. + */ + public abstract readonly type: InferenceProfileType; + + /** + * Grants appropriate permissions to use the cross-region inference profile. + * Does not grant permissions to use the model in the profile. + */ + grantProfileUsage(grantee: IGrantable): Grant { + const grant = Grant.addToPrincipal({ + grantee: grantee, + actions: ["bedrock:GetInferenceProfile", "bedrock:ListInferenceProfiles"], + resourceArns: [this.inferenceProfileArn], + scope: this, + }); + return grant; + } +} diff --git a/src/cdk-lib/bedrock/inference-profiles/cross-region-inference-profile.ts b/src/cdk-lib/bedrock/inference-profiles/cross-region-inference-profile.ts new file mode 100644 index 00000000..829030b2 --- /dev/null +++ b/src/cdk-lib/bedrock/inference-profiles/cross-region-inference-profile.ts @@ -0,0 +1,79 @@ +import { Arn, ArnFormat, Aws, Resource } from "aws-cdk-lib"; +import { BedrockFoundationModel } from "../models"; +import { IConstruct } from "constructs"; +import { IInferenceProfile, InferenceProfileBase, InferenceProfileType } from "./common"; +import { IModel } from "aws-cdk-lib/aws-bedrock"; +import { IGrantable, Grant } from "aws-cdk-lib/aws-iam"; + +export enum CrossRegionInferenceProfileRegion { + /** + * EU: Frankfurt (eu-central-1), Ireland (eu-west-1), Paris (eu-west-3) + */ + EU = "eu", + /** + * US: N. Virginia (us-east-1), Oregon (us-west-2) + */ + US = "us", + /** + * This might include: ap-northeast-1, ap-northeast-2, ap-south-1, ap-southeast-1, and ap-southeast-2 + */ + APAC = "apac", +} + +/****************************************************************************** + * PROPS FOR NEW CONSTRUCT + *****************************************************************************/ +export interface CrossRegionInferenceProfileProps { + /** + * The geographic region where the traffic is going to be distributed. Routing + * factors in user traffic, demand and utilization of resources. + */ + readonly geoRegion: CrossRegionInferenceProfileRegion; + /** + * A model supporting cross-region inference. + * @see https://docs.aws.amazon.com/bedrock/latest/userguide/cross-region-inference-support.html + */ + readonly model: BedrockFoundationModel; +} + +/****************************************************************************** + * NEW CONSTRUCT DEFINITION + *****************************************************************************/ +/** + * Cross-region inference enables you to seamlessly manage unplanned traffic + * bursts by utilizing compute across different AWS Regions. With cross-region + * inference, you can distribute traffic across multiple AWS Regions, enabling + * higher throughput and enhanced resilience during periods of peak demands. + * @see https://docs.aws.amazon.com/bedrock/latest/userguide/cross-region-inference.html + */ +export class CrossRegionInferenceProfile extends InferenceProfileBase implements IModel { + /** + * @example 'us.anthropic.claude-3-5-sonnet-20240620-v1:0' + */ + public readonly inferenceProfileId: string; + /** + * @example 'arn:aws:bedrock:us-east-1:123456789012:inference-profile/us.anthropic.claude-3-5-sonnet-20240620-v1:0' + */ + public readonly inferenceProfileArn: string; + public readonly type: InferenceProfileType; + public readonly inferenceProfileModel: IModel; + /** This equals to the inferenceProfileArn property, useful just to implement IModel interface*/ + public readonly modelArn: string; + + constructor(scope: IConstruct, id: string, props: CrossRegionInferenceProfileProps) { + super(scope, id); + if (!props.model.supportsCrossRegion) { + throw new Error(`Model ${props.model.modelId} does not support cross-region inference`); + } + this.inferenceProfileId = `${props.geoRegion}.${props.model.modelId}`; + this.inferenceProfileArn = Arn.format({ + partition: Aws.PARTITION, + service: "bedrock", + account: Aws.ACCOUNT_ID, + region: Aws.REGION, + resource: "inference-profile", + resourceName: this.inferenceProfileId, + arnFormat: ArnFormat.SLASH_RESOURCE_NAME, + }); + } +} diff --git a/src/cdk-lib/bedrock/models.ts b/src/cdk-lib/bedrock/models.ts index bc8add0f..b6d93111 100644 --- a/src/cdk-lib/bedrock/models.ts +++ b/src/cdk-lib/bedrock/models.ts @@ -11,10 +11,9 @@ * and limitations under the License. */ - -import { Stack } from 'aws-cdk-lib'; -import { IModel } from 'aws-cdk-lib/aws-bedrock'; -import { IConstruct } from 'constructs'; +import { Arn, ArnFormat, Aws, Stack } from "aws-cdk-lib"; +import { IModel } from "aws-cdk-lib/aws-bedrock"; +import { IConstruct } from "constructs"; export interface BedrockFoundationModelProps { /** @@ -29,6 +28,11 @@ export interface BedrockFoundationModelProps { * @default - false */ readonly supportsKnowledgeBase?: boolean; + /** + * Can be used with a Cross-Region Inference Profile + * @default - false + */ + readonly supportsCrossRegion?: boolean; /** * Embedding models have different vector dimensions. * Only applicable for embedding models. @@ -42,82 +46,134 @@ export interface BedrockFoundationModelProps { * If you need to use a model name that doesn't exist as a static member, you * can instantiate a `BedrockFoundationModel` object, e.g: `new BedrockFoundationModel('my-model')`. */ -export class BedrockFoundationModel { - public static readonly ANTHROPIC_CLAUDE_V2 = new BedrockFoundationModel( - 'anthropic.claude-v2', - { supportsAgents: true }, - ); - public static readonly ANTHROPIC_CLAUDE_V2_1 = new BedrockFoundationModel( - 'anthropic.claude-v2:1', - { supportsAgents: true }, - ); - public static readonly ANTHROPIC_CLAUDE_INSTANT_V1_2 = new BedrockFoundationModel( - 'anthropic.claude-instant-v1', - { supportsAgents: true }, - ); - public static readonly AMAZON_TITAN_TEXT_EXPRESS_V1 = new BedrockFoundationModel( - 'amazon.titan-text-express-v1', - { supportsAgents: true }, - ); - public static readonly ANTHROPIC_CLAUDE_3_5_HAIKU_V1_0 = new BedrockFoundationModel( - 'anthropic.claude-3-5-haiku-20241022-v1:0', - { supportsAgents: true }, - ); +export class BedrockFoundationModel implements IModel { + /**************************************************************************** + * AMAZON + ***************************************************************************/ + public static readonly AMAZON_TITAN_TEXT_EXPRESS_V1 = new BedrockFoundationModel("amazon.titan-text-express-v1", { + supportsAgents: true, + }); + + public static readonly AMAZON_TITAN_PREMIER_V1_0 = new BedrockFoundationModel("amazon.titan-text-premier-v1:0", { + supportsAgents: true, + }); + + public static readonly TITAN_EMBED_TEXT_V1 = new BedrockFoundationModel("amazon.titan-embed-text-v1", { + supportsKnowledgeBase: true, + vectorDimensions: 1536, + }); + + public static readonly TITAN_EMBED_TEXT_V2_1024 = new BedrockFoundationModel("amazon.titan-embed-text-v2:0", { + supportsKnowledgeBase: true, + vectorDimensions: 1024, + }); + + public static readonly TITAN_EMBED_TEXT_V2_512 = new BedrockFoundationModel("amazon.titan-embed-text-v2:0", { + supportsKnowledgeBase: true, + vectorDimensions: 512, + }); + + public static readonly TITAN_EMBED_TEXT_V2_256 = new BedrockFoundationModel("amazon.titan-embed-text-v2:0", { + supportsKnowledgeBase: true, + vectorDimensions: 256, + }); + /**************************************************************************** + * ANTHROPIC + ***************************************************************************/ public static readonly ANTHROPIC_CLAUDE_3_5_SONNET_V2_0 = new BedrockFoundationModel( - 'anthropic.claude-3-5-sonnet-20241022-v2:0', - { supportsAgents: true }, + "anthropic.claude-3-5-sonnet-20241022-v2:0", + { supportsAgents: true, supportsCrossRegion: true } ); + public static readonly ANTHROPIC_CLAUDE_3_5_SONNET_V1_0 = new BedrockFoundationModel( - 'anthropic.claude-3-5-sonnet-20240620-v1:0', - { supportsAgents: true }, + "anthropic.claude-3-5-sonnet-20240620-v1:0", + { supportsAgents: true, supportsCrossRegion: true } + ); + + public static readonly ANTHROPIC_CLAUDE_3_5_HAIKU_V1_0 = new BedrockFoundationModel( + "anthropic.claude-3-5-haiku-20241022-v1:0", + { supportsAgents: true, supportsCrossRegion: true } ); + public static readonly ANTHROPIC_CLAUDE_OPUS_V1_0 = new BedrockFoundationModel( - 'anthropic.claude-3-opus-20240229-v1:0', - { supportsAgents: true }, + "anthropic.claude-3-opus-20240229-v1:0", + { supportsAgents: true } ); + public static readonly ANTHROPIC_CLAUDE_SONNET_V1_0 = new BedrockFoundationModel( - 'anthropic.claude-3-sonnet-20240229-v1:0', - { supportsAgents: true }, + "anthropic.claude-3-sonnet-20240229-v1:0", + { supportsAgents: true, supportsCrossRegion: true } ); + public static readonly ANTHROPIC_CLAUDE_HAIKU_V1_0 = new BedrockFoundationModel( - 'anthropic.claude-3-haiku-20240307-v1:0', - { supportsAgents: true }, - ); - public static readonly AMAZON_TITAN_PREMIER_V1_0 = new BedrockFoundationModel( - 'amazon.titan-text-premier-v1:0', - { supportsAgents: true }, - ); - public static readonly TITAN_EMBED_TEXT_V1 = new BedrockFoundationModel( - 'amazon.titan-embed-text-v1', - { supportsKnowledgeBase: true, vectorDimensions: 1536 }, - ); - public static readonly TITAN_EMBED_TEXT_V2_1024 = new BedrockFoundationModel( - 'amazon.titan-embed-text-v2:0', - { supportsKnowledgeBase: true, vectorDimensions: 1024 }, - ); - public static readonly TITAN_EMBED_TEXT_V2_512 = new BedrockFoundationModel( - 'amazon.titan-embed-text-v2:0', - { supportsKnowledgeBase: true, vectorDimensions: 512 }, - ); - public static readonly TITAN_EMBED_TEXT_V2_256 = new BedrockFoundationModel( - 'amazon.titan-embed-text-v2:0', - { supportsKnowledgeBase: true, vectorDimensions: 256 }, + "anthropic.claude-3-haiku-20240307-v1:0", + { supportsAgents: true, supportsCrossRegion: true } ); - public static readonly COHERE_EMBED_ENGLISH_V3 = new BedrockFoundationModel( - 'cohere.embed-english-v3', - { supportsKnowledgeBase: true, vectorDimensions: 1024 }, - ); - public static readonly COHERE_EMBED_MULTILINGUAL_V3 = new BedrockFoundationModel( - 'cohere.embed-multilingual-v3', - { supportsKnowledgeBase: true, vectorDimensions: 1024 }, + + public static readonly ANTHROPIC_CLAUDE_V2_1 = new BedrockFoundationModel("anthropic.claude-v2:1", { + supportsAgents: true, + }); + + public static readonly ANTHROPIC_CLAUDE_V2 = new BedrockFoundationModel("anthropic.claude-v2", { + supportsAgents: true, + }); + + public static readonly ANTHROPIC_CLAUDE_INSTANT_V1_2 = new BedrockFoundationModel("anthropic.claude-instant-v1", { + supportsAgents: true, + }); + + /**************************************************************************** + * COHERE + ***************************************************************************/ + public static readonly COHERE_EMBED_ENGLISH_V3 = new BedrockFoundationModel("cohere.embed-english-v3", { + supportsKnowledgeBase: true, + vectorDimensions: 1024, + }); + + public static readonly COHERE_EMBED_MULTILINGUAL_V3 = new BedrockFoundationModel("cohere.embed-multilingual-v3", { + supportsKnowledgeBase: true, + vectorDimensions: 1024, + }); + + /**************************************************************************** + * META + ***************************************************************************/ + public static readonly META_LLAMA_3_2_11B_INSTRUCT_V1 = new BedrockFoundationModel( + "meta.llama3-2-11b-instruct-v1:0", + { + supportsCrossRegion: true, + } ); + public static readonly META_LLAMA_3_2_3B_INSTRUCT_V1 = new BedrockFoundationModel("meta.llama3-2-3b-instruct-v1:0", { + supportsCrossRegion: true, + }); + + public static readonly META_LLAMA_3_2_1B_INSTRUCT_V1 = new BedrockFoundationModel("meta.llama3-2-1b-instruct-v1:0", { + supportsCrossRegion: true, + }); + + /**************************************************************************** + * Constructor + ***************************************************************************/ public readonly modelId: string; + public readonly modelArn: string; public readonly supportsAgents: boolean; + public readonly supportsCrossRegion: boolean; public readonly vectorDimensions?: number; public readonly supportsKnowledgeBase: boolean; constructor(value: string, props: BedrockFoundationModelProps = {}) { this.modelId = value; + this.modelArn = Arn.format({ + partition: Aws.PARTITION, + service: "bedrock", + region: Aws.REGION, + account: Aws.ACCOUNT_ID, + resource: "foundation-model", + resourceName: this.modelId, + arnFormat: ArnFormat.SLASH_RESOURCE_NAME, + }); + this.supportsCrossRegion = props.supportsCrossRegion ?? false; this.supportsAgents = props.supportsAgents ?? false; this.vectorDimensions = props.vectorDimensions; this.supportsKnowledgeBase = props.supportsKnowledgeBase ?? false; @@ -132,11 +188,10 @@ export class BedrockFoundationModel { * `arn:${Partition}:bedrock:${Region}::foundation-model/${ResourceId}` */ asArn(construct: IConstruct): string { - const region = Stack.of(construct).region; - return `arn:aws:bedrock:${region}::foundation-model/${this.modelId}`; + return this.modelArn; } asIModel(construct: IConstruct): IModel { - return { modelArn: this.asArn(construct) }; + return this; } } diff --git a/test/cdk-lib/bedrock/application-inference-profile.test.ts b/test/cdk-lib/bedrock/application-inference-profile.test.ts deleted file mode 100644 index bcb079db..00000000 --- a/test/cdk-lib/bedrock/application-inference-profile.test.ts +++ /dev/null @@ -1,123 +0,0 @@ -/** - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance - * with the License. A copy of the License is located at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES - * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions - * and limitations under the License. - */ -import * as cdk from 'aws-cdk-lib'; -import { Match, Template } from 'aws-cdk-lib/assertions'; -import { CfnApplicationInferenceProfile } from 'aws-cdk-lib/aws-bedrock'; -import { AwsSolutionsChecks } from 'cdk-nag'; -import * as bedrock from '../../../src/cdk-lib/bedrock'; - -describe('CDK-Created-Application-Inference-Profile', () => { - let stack: cdk.Stack; - - beforeEach(() => { - const app = new cdk.App(); - cdk.Aspects.of(app).add(new AwsSolutionsChecks()); - stack = new cdk.Stack(app, 'TestStack'); - }); - - test('Basic Creation with a foundation model', () => { - new bedrock.ApplicationInferenceProfile(stack, 'TestAIP', { - inferenceProfileName: 'TestAIP', - description: 'This is a test application inf profile', - modelSource: bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0.asArn(stack), - tags: [ - { - key: 'test-key', - value: 'test-value', - }, - ], - }); - - Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::ApplicationInferenceProfile', { - InferenceProfileName: 'TestAIP', - Description: 'This is a test application inf profile', - ModelSource: { - CopyFrom: { - 'Fn::Join': [ - '', - [ - 'arn:aws:bedrock:', - { - Ref: 'AWS::Region', - }, - '::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0', - ], - ], - }, - }, - Tags: [ - { - Key: 'test-key', - Value: 'test-value', - }, - ], - }); - }); - - test('Basic Creation with a system defined inference profile', () => { - new bedrock.ApplicationInferenceProfile(stack, 'TestAIPSystem', { - inferenceProfileName: 'TestAIPSystem', - modelSource: 'arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0', - }); - - Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::ApplicationInferenceProfile', { - InferenceProfileName: 'TestAIPSystem', - Description: Match.absent(), - ModelSource: { - CopyFrom: 'arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0', - }, - }); - }); -}); - -describe('Imported-ApplicationInferenceProfile', () => { - let stack: cdk.Stack; - - beforeEach(() => { - const app = new cdk.App(); - cdk.Aspects.of(app).add(new AwsSolutionsChecks()); - stack = new cdk.Stack(app, 'TestStack2', { - env: { - account: '123456789012', - region: 'us-east-1', - }, - }); - }); - - test('Basic Import - from attributes', () => { - const aip = bedrock.ApplicationInferenceProfile.fromApplicationInferenceProfileAttributes(stack, 'TestAIP', { - inferenceProfileArn: 'arn:aws:bedrock:us-east-1:123456789012:application-inference-profile/cew2pa5r8hog', - inferenceProfileIdentifier: 'arn:aws:bedrock:us-east-1:123456789012:application-inference-profile/cew2pa5r8hog', - }); - - expect(aip.inferenceProfileArn).toBe('arn:aws:bedrock:us-east-1:123456789012:application-inference-profile/cew2pa5r8hog'); - expect(aip.inferenceProfileId).toBe('cew2pa5r8hog'); - expect(aip.inferenceProfileIdentifier).toBe('arn:aws:bedrock:us-east-1:123456789012:application-inference-profile/cew2pa5r8hog'); - }); - - test('Basic Import - from cfn', () => { - - const cfnapp = new CfnApplicationInferenceProfile(stack, 'mytest', { - inferenceProfileName: 'mytest', - modelSource: { - copyFrom: 'arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0', - }, - }); - - const aip2 = bedrock.ApplicationInferenceProfile.fromCfnApplicationInferenceProfile(cfnapp); - - expect(aip2.inferenceProfileArn).toBe(cfnapp.attrInferenceProfileArn); - expect(aip2.inferenceProfileId).toBe(cfnapp.attrInferenceProfileId); - expect(aip2.inferenceProfileIdentifier).toBe(cfnapp.attrInferenceProfileIdentifier); - }); -}); diff --git a/test/cdk-lib/bedrock/inference-profile.test.ts b/test/cdk-lib/bedrock/inference-profile.test.ts new file mode 100644 index 00000000..b97ed491 --- /dev/null +++ b/test/cdk-lib/bedrock/inference-profile.test.ts @@ -0,0 +1,117 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance + * with the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES + * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ +import * as cdk from "aws-cdk-lib"; +import { Match, Template } from "aws-cdk-lib/assertions"; +import { CfnApplicationInferenceProfile } from "aws-cdk-lib/aws-bedrock"; +import { AwsSolutionsChecks } from "cdk-nag"; +import * as bedrock from "../../../src/cdk-lib/bedrock"; + +describe("CDK-Created-Application-Inference-Profile", () => { + let stack: cdk.Stack; + + beforeEach(() => { + const app = new cdk.App(); + cdk.Aspects.of(app).add(new AwsSolutionsChecks()); + stack = new cdk.Stack(app, "TestStack"); + }); + + test("Basic Creation with a foundation model", () => { + new bedrock.ApplicationInferenceProfile(stack, "TestAIP", { + inferenceProfileName: "TestAIP", + description: "This is a test application inf profile", + modelSource: bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0, + tags: [{ key: "test-key", value: "test-value" }], + }); + + Template.fromStack(stack).hasResourceProperties("AWS::Bedrock::ApplicationInferenceProfile", { + InferenceProfileName: "TestAIP", + Description: "This is a test application inf profile", + ModelSource: { + CopyFrom: { + "Fn::Join": [ + "", + [ + "arn:aws:bedrock:", + { + Ref: "AWS::Region", + }, + "::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0", + ], + ], + }, + }, + Tags: [ + { + Key: "test-key", + Value: "test-value", + }, + ], + }); + }); + + test("Basic Creation with a system defined inference profile", () => { + new bedrock.ApplicationInferenceProfile(stack, "TestAIPSystem", { + inferenceProfileName: "TestAIPSystem", + modelSource: bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_3_5_SONNET_V2_0, + }); + + Template.fromStack(stack).hasResourceProperties("AWS::Bedrock::ApplicationInferenceProfile", { + InferenceProfileName: "TestAIPSystem", + Description: Match.absent(), + ModelSource: { + CopyFrom: "arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0", + }, + }); + }); +}); + +describe("Imported-ApplicationInferenceProfile", () => { + let stack: cdk.Stack; + + beforeEach(() => { + const app = new cdk.App(); + cdk.Aspects.of(app).add(new AwsSolutionsChecks()); + stack = new cdk.Stack(app, "TestStack2", { + env: { + account: "123456789012", + region: "us-east-1", + }, + }); + }); + + test("Basic Import - from attributes", () => { + const aip = bedrock.ApplicationInferenceProfile.fromApplicationInferenceProfileAttributes(stack, "TestAIP", { + inferenceProfileArn: "arn:aws:bedrock:us-east-1:123456789012:application-inference-profile/cew2pa5r8hog", + inferenceProfileIdentifier: "arn:aws:bedrock:us-east-1:123456789012:application-inference-profile/cew2pa5r8hog", + }); + + expect(aip.inferenceProfileArn).toBe( + "arn:aws:bedrock:us-east-1:123456789012:application-inference-profile/cew2pa5r8hog" + ); + expect(aip.inferenceProfileId).toBe("cew2pa5r8hog"); + }); + + test("Basic Import - from cfn", () => { + const cfnapp = new CfnApplicationInferenceProfile(stack, "mytest", { + inferenceProfileName: "mytest", + modelSource: { + copyFrom: "arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0", + }, + }); + + const aip2 = bedrock.ApplicationInferenceProfile.fromCfnApplicationInferenceProfile(cfnapp); + + expect(aip2.inferenceProfileArn).toBe(cfnapp.attrInferenceProfileArn); + expect(aip2.inferenceProfileId).toBe(cfnapp.attrInferenceProfileId); + }); +}); From 3e376b72d0f70c0d5e3df27175baf5b5ee289e4e Mon Sep 17 00:00:00 2001 From: Rafael Mosca Date: Fri, 15 Nov 2024 19:07:02 +0100 Subject: [PATCH 10/22] feat(bedrock): add IInvokable --- src/cdk-lib/bedrock/data-sources/parsing.ts | 30 ++-- .../application-inference-profile.ts | 12 +- .../bedrock/inference-profiles/common.ts | 1 - .../cross-region-inference-profile.ts | 18 +- src/cdk-lib/bedrock/models.ts | 11 +- src/cdk-lib/bedrock/prompts/prompt.ts | 28 +-- .../data-sources/s3-data-source.test.ts | 170 +++++++++--------- .../cdk-lib/bedrock/inference-profile.test.ts | 95 ++++++++++ 8 files changed, 232 insertions(+), 133 deletions(-) diff --git a/src/cdk-lib/bedrock/data-sources/parsing.ts b/src/cdk-lib/bedrock/data-sources/parsing.ts index 1599382e..8be6dff6 100644 --- a/src/cdk-lib/bedrock/data-sources/parsing.ts +++ b/src/cdk-lib/bedrock/data-sources/parsing.ts @@ -11,9 +11,10 @@ * and limitations under the License. */ -import { CfnDataSource, IModel } from 'aws-cdk-lib/aws-bedrock'; -import { PolicyStatement } from 'aws-cdk-lib/aws-iam'; -import { DEFAULT_PARSING_PROMPT } from './default-parsing-prompt'; +import { CfnDataSource, IModel } from "aws-cdk-lib/aws-bedrock"; +import { PolicyStatement } from "aws-cdk-lib/aws-iam"; +import { DEFAULT_PARSING_PROMPT } from "./default-parsing-prompt"; +import { IInvokable } from "../models"; /** * Enum representing the types of parsing strategies available for Amazon Bedrock Knowledge Bases. @@ -22,7 +23,7 @@ enum ParsingStategyType { /** * Uses a Bedrock Foundation Model for advanced parsing of non-textual information from documents. */ - FOUNDATION_MODEL = 'BEDROCK_FOUNDATION_MODEL' + FOUNDATION_MODEL = "BEDROCK_FOUNDATION_MODEL", } /** @@ -33,7 +34,7 @@ export interface FoundationModelParsingStategyProps { * The Foundation Model to use for parsing non-textual information. * Currently supported models are Claude 3 Sonnet and Claude 3 Haiku. */ - readonly parsingModel: IModel; + readonly parsingModel: IInvokable; /** * Custom prompt to instruct the parser on how to interpret the document. @@ -41,7 +42,6 @@ export interface FoundationModelParsingStategyProps { * @default - Uses the default instruction prompt as provided in the AWS Console. */ readonly parsingPrompt?: string; - } /** @@ -49,7 +49,6 @@ export interface FoundationModelParsingStategyProps { * @see https://docs.aws.amazon.com/bedrock/latest/userguide/kb-chunking-parsing.html#kb-advanced-parsing */ export abstract class ParsingStategy { - // ------------------------------------------------------ // FM Parsing Strategy // ------------------------------------------------------ @@ -65,7 +64,7 @@ export abstract class ParsingStategy { /** The CloudFormation property representation of this configuration */ public readonly configuration = { bedrockFoundationModelConfiguration: { - modelArn: props.parsingModel.modelArn, + modelArn: props.parsingModel.invokableArn, parsingPrompt: { parsingPromptText: props.parsingPrompt ?? DEFAULT_PARSING_PROMPT, }, @@ -74,12 +73,14 @@ export abstract class ParsingStategy { }; public generatePolicyStatements(): PolicyStatement[] { - return [new PolicyStatement({ - actions: ['bedrock:InvokeModel'], - resources: [props.parsingModel.modelArn], - })]; + return [ + new PolicyStatement({ + actions: ["bedrock:InvokeModel"], + resources: [props.parsingModel.invokableArn], + }), + ]; } - }; + } return new FoundationModelTransformation(); } @@ -90,7 +91,4 @@ export abstract class ParsingStategy { public abstract configuration: CfnDataSource.ParsingConfigurationProperty; public abstract generatePolicyStatements(): PolicyStatement[]; - - } - diff --git a/src/cdk-lib/bedrock/inference-profiles/application-inference-profile.ts b/src/cdk-lib/bedrock/inference-profiles/application-inference-profile.ts index cbaf629b..a1b8508d 100644 --- a/src/cdk-lib/bedrock/inference-profiles/application-inference-profile.ts +++ b/src/cdk-lib/bedrock/inference-profiles/application-inference-profile.ts @@ -10,10 +10,11 @@ * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions * and limitations under the License. */ -import { CfnTag, Arn, ArnFormat, Tag } from "aws-cdk-lib"; +import { CfnTag, Arn, ArnFormat } from "aws-cdk-lib"; import * as bedrock from "aws-cdk-lib/aws-bedrock"; import { Construct } from "constructs"; import { IInferenceProfile, InferenceProfileBase, InferenceProfileType } from "./common"; +import { IInvokable } from "../models"; /****************************************************************************** * PROPS FOR NEW CONSTRUCT @@ -73,7 +74,7 @@ export interface ApplicationInferenceProfileAttributes { * @resource AWS::Bedrock::ApplicationInferenceProfile * @see https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-create.html */ -export class ApplicationInferenceProfile extends InferenceProfileBase { +export class ApplicationInferenceProfile extends InferenceProfileBase implements IInvokable { /** * Import a ApplicationInferenceProfile given its attributes */ @@ -136,6 +137,10 @@ export class ApplicationInferenceProfile extends InferenceProfileBase { * Time Stamp for ApplicationInferenceProfile update. */ public readonly updatedAt: string; + /** + * This equals to the inferenceProfileArn property, useful just to implement IInvokable interface. + */ + public readonly invokableArn: string; /** * Instance of CfnApplicationInferenceProfile. */ @@ -164,5 +169,8 @@ export class ApplicationInferenceProfile extends InferenceProfileBase { this.type = this._resource.attrType as InferenceProfileType; this.createdAt = this._resource.attrCreatedAt; this.updatedAt = this._resource.attrUpdatedAt; + + // Needed to Implement IInvokable + this.invokableArn = this.inferenceProfileArn; } } diff --git a/src/cdk-lib/bedrock/inference-profiles/common.ts b/src/cdk-lib/bedrock/inference-profiles/common.ts index 52fc487f..d7845d21 100644 --- a/src/cdk-lib/bedrock/inference-profiles/common.ts +++ b/src/cdk-lib/bedrock/inference-profiles/common.ts @@ -11,7 +11,6 @@ * and limitations under the License. */ import { IResource, Resource } from "aws-cdk-lib"; -import { IModel } from "aws-cdk-lib/aws-bedrock"; import { Grant, IGrantable } from "aws-cdk-lib/aws-iam"; /** These are the values used by the API when using aws bedrock get-inference-profile --inference-profile-identifier XXXXXXX */ diff --git a/src/cdk-lib/bedrock/inference-profiles/cross-region-inference-profile.ts b/src/cdk-lib/bedrock/inference-profiles/cross-region-inference-profile.ts index 829030b2..6ca47e24 100644 --- a/src/cdk-lib/bedrock/inference-profiles/cross-region-inference-profile.ts +++ b/src/cdk-lib/bedrock/inference-profiles/cross-region-inference-profile.ts @@ -1,9 +1,7 @@ -import { Arn, ArnFormat, Aws, Resource } from "aws-cdk-lib"; -import { BedrockFoundationModel } from "../models"; +import { Arn, ArnFormat, Aws } from "aws-cdk-lib"; +import { BedrockFoundationModel, IInvokable } from "../models"; import { IConstruct } from "constructs"; -import { IInferenceProfile, InferenceProfileBase, InferenceProfileType } from "./common"; -import { IModel } from "aws-cdk-lib/aws-bedrock"; -import { IGrantable, Grant } from "aws-cdk-lib/aws-iam"; +import { InferenceProfileBase, InferenceProfileType } from "./common"; export enum CrossRegionInferenceProfileRegion { /** @@ -46,7 +44,7 @@ export interface CrossRegionInferenceProfileProps { * higher throughput and enhanced resilience during periods of peak demands. * @see https://docs.aws.amazon.com/bedrock/latest/userguide/cross-region-inference.html */ -export class CrossRegionInferenceProfile extends InferenceProfileBase implements IModel { +export class CrossRegionInferenceProfile extends InferenceProfileBase implements IInvokable { /** * @example 'us.anthropic.claude-3-5-sonnet-20240620-v1:0' */ @@ -56,9 +54,9 @@ export class CrossRegionInferenceProfile extends InferenceProfileBase implements */ public readonly inferenceProfileArn: string; public readonly type: InferenceProfileType; - public readonly inferenceProfileModel: IModel; - /** This equals to the inferenceProfileArn property, useful just to implement IModel interface*/ - public readonly modelArn: string; + public readonly inferenceProfileModel: IInvokable; + /** This equals to the inferenceProfileArn property, useful just to implement IInvokable interface*/ + public readonly invokableArn: string; constructor(scope: IConstruct, id: string, props: CrossRegionInferenceProfileProps) { super(scope, id); @@ -75,5 +73,7 @@ export class CrossRegionInferenceProfile extends InferenceProfileBase implements resourceName: this.inferenceProfileId, arnFormat: ArnFormat.SLASH_RESOURCE_NAME, }); + // Needed to Implement IInvokable + this.invokableArn = this.inferenceProfileArn; } } diff --git a/src/cdk-lib/bedrock/models.ts b/src/cdk-lib/bedrock/models.ts index b6d93111..7514d4c8 100644 --- a/src/cdk-lib/bedrock/models.ts +++ b/src/cdk-lib/bedrock/models.ts @@ -15,6 +15,13 @@ import { Arn, ArnFormat, Aws, Stack } from "aws-cdk-lib"; import { IModel } from "aws-cdk-lib/aws-bedrock"; import { IConstruct } from "constructs"; +export interface IInvokable { + /** + * The ARN of the Bedrock invokable object. + */ + readonly invokableArn: string; +} + export interface BedrockFoundationModelProps { /** * Bedrock Agents can use this model. @@ -46,7 +53,7 @@ export interface BedrockFoundationModelProps { * If you need to use a model name that doesn't exist as a static member, you * can instantiate a `BedrockFoundationModel` object, e.g: `new BedrockFoundationModel('my-model')`. */ -export class BedrockFoundationModel implements IModel { +export class BedrockFoundationModel implements IInvokable { /**************************************************************************** * AMAZON ***************************************************************************/ @@ -158,6 +165,7 @@ export class BedrockFoundationModel implements IModel { ***************************************************************************/ public readonly modelId: string; public readonly modelArn: string; + public readonly invokableArn: string; public readonly supportsAgents: boolean; public readonly supportsCrossRegion: boolean; public readonly vectorDimensions?: number; @@ -173,6 +181,7 @@ export class BedrockFoundationModel implements IModel { resourceName: this.modelId, arnFormat: ArnFormat.SLASH_RESOURCE_NAME, }); + this.invokableArn = this.modelArn; this.supportsCrossRegion = props.supportsCrossRegion ?? false; this.supportsAgents = props.supportsAgents ?? false; this.vectorDimensions = props.vectorDimensions; diff --git a/src/cdk-lib/bedrock/prompts/prompt.ts b/src/cdk-lib/bedrock/prompts/prompt.ts index c4229dd2..6924bd42 100644 --- a/src/cdk-lib/bedrock/prompts/prompt.ts +++ b/src/cdk-lib/bedrock/prompts/prompt.ts @@ -11,15 +11,15 @@ * and limitations under the License. */ -import { Arn, ArnFormat, aws_kms as kms, Lazy, aws_bedrock as bedrock, Resource } from 'aws-cdk-lib'; -import { IModel } from 'aws-cdk-lib/aws-bedrock'; -import { Grant, IGrantable } from 'aws-cdk-lib/aws-iam'; -import { IKey } from 'aws-cdk-lib/aws-kms'; -import { md5hash } from 'aws-cdk-lib/core/lib/helpers-internal'; -import { Construct } from 'constructs'; +import { Arn, ArnFormat, aws_kms as kms, Lazy, aws_bedrock as bedrock, Resource } from "aws-cdk-lib"; +import { Grant, IGrantable } from "aws-cdk-lib/aws-iam"; +import { IKey } from "aws-cdk-lib/aws-kms"; +import { md5hash } from "aws-cdk-lib/core/lib/helpers-internal"; +import { Construct } from "constructs"; +import { IInvokable } from "../models"; export enum PromptTemplateType { - TEXT = 'TEXT', + TEXT = "TEXT", } export interface CommonPromptVariantProps { @@ -31,7 +31,7 @@ export interface CommonPromptVariantProps { * The model which is used to run the prompt. The model could be a foundation * model, a custom model, or a provisioned model. */ - readonly model: IModel; + readonly model: IInvokable; } export interface TextPromptVariantProps extends CommonPromptVariantProps { @@ -66,7 +66,7 @@ export abstract class PromptVariant { return { name: props.variantName, templateType: PromptTemplateType.TEXT, - modelId: props.model.modelArn, + modelId: props.model.invokableArn, inferenceConfiguration: { text: { ...props.inferenceConfiguration }, }, @@ -155,7 +155,7 @@ export abstract class PromptBase extends Resource implements IPrompt { return Grant.addToPrincipal({ grantee, resourceArns: [this.promptArn], - actions: ['bedrock:GetPrompt'], + actions: ["bedrock:GetPrompt"], scope: this, }); } @@ -232,7 +232,7 @@ export class Prompt extends Construct implements IPrompt { class Import extends PromptBase { public readonly promptArn = attrs.promptArn; public readonly promptId = formattedArn.resourceName!; - public readonly promptVersion = attrs.promptVersion ?? 'DRAFT'; + public readonly promptVersion = attrs.promptVersion ?? "DRAFT"; public readonly kmsKey = attrs.kmsKey; } @@ -314,7 +314,7 @@ export class Prompt extends Construct implements IPrompt { // ------------------------------------------------------ // L1 Instantiation // ------------------------------------------------------ - this._resource = new bedrock.CfnPrompt(this, 'Prompt', cfnProps); + this._resource = new bedrock.CfnPrompt(this, "Prompt", cfnProps); this.promptArn = this._resource.attrArn; this.promptId = this._resource.attrId; @@ -334,7 +334,7 @@ export class Prompt extends Construct implements IPrompt { const matchesPattern = /^([0-9a-zA-Z][_-]?){1,100}$/.test(this.promptName); if (!matchesPattern) { errors.push( - 'Valid characters are a-z, A-Z, 0-9, _ (underscore) and - (hyphen). And must not begin with a hyphen', + "Valid characters are a-z, A-Z, 0-9, _ (underscore) and - (hyphen). And must not begin with a hyphen" ); } if (errors.length > 0) { @@ -350,7 +350,7 @@ export class Prompt extends Construct implements IPrompt { const errors: string[] = []; if (this.variants.length > 3) { errors.push( - `Error: Too many variants specified. The maximum allowed is 3, but you have provided ${this.variants.length} variants.`, + `Error: Too many variants specified. The maximum allowed is 3, but you have provided ${this.variants.length} variants.` ); } return errors; diff --git a/test/cdk-lib/bedrock/data-sources/s3-data-source.test.ts b/test/cdk-lib/bedrock/data-sources/s3-data-source.test.ts index 77490680..77e0258e 100644 --- a/test/cdk-lib/bedrock/data-sources/s3-data-source.test.ts +++ b/test/cdk-lib/bedrock/data-sources/s3-data-source.test.ts @@ -11,16 +11,15 @@ * and limitations under the License. */ -import * as cdk from 'aws-cdk-lib'; -import { Template, Match } from 'aws-cdk-lib/assertions'; -import { FoundationModel, FoundationModelIdentifier } from 'aws-cdk-lib/aws-bedrock'; -import { Code, Function, Runtime } from 'aws-cdk-lib/aws-lambda'; -import * as s3 from 'aws-cdk-lib/aws-s3'; -import { AwsSolutionsChecks } from 'cdk-nag'; -import * as bedrock from '../../../../src/cdk-lib/bedrock'; -import * as foundationModels from '../../../../src/cdk-lib/bedrock/models'; +import * as cdk from "aws-cdk-lib"; +import { Template, Match } from "aws-cdk-lib/assertions"; +import { Code, Function, Runtime } from "aws-cdk-lib/aws-lambda"; +import * as s3 from "aws-cdk-lib/aws-s3"; +import { AwsSolutionsChecks } from "cdk-nag"; +import * as bedrock from "../../../../src/cdk-lib/bedrock"; +import * as foundationModels from "../../../../src/cdk-lib/bedrock/models"; -describe('S3 Data Source', () => { +describe("S3 Data Source", () => { let stack: cdk.Stack; let bucket: s3.Bucket; let kb: bedrock.KnowledgeBase; @@ -28,48 +27,46 @@ describe('S3 Data Source', () => { beforeEach(() => { const app = new cdk.App(); cdk.Aspects.of(app).add(new AwsSolutionsChecks()); - stack = new cdk.Stack(app, 'TestStack'); - bucket = new s3.Bucket(stack, 'TestBucket'); - kb = new bedrock.KnowledgeBase(stack, 'KB', { + stack = new cdk.Stack(app, "TestStack"); + bucket = new s3.Bucket(stack, "TestBucket"); + kb = new bedrock.KnowledgeBase(stack, "KB", { embeddingsModel: foundationModels.BedrockFoundationModel.TITAN_EMBED_TEXT_V2_1024, }); }); - test('Method', () => { + test("Method", () => { kb.addS3DataSource({ bucket, - dataSourceName: 'TestDataSource', + dataSourceName: "TestDataSource", }); - - Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::DataSource', { + Template.fromStack(stack).hasResourceProperties("AWS::Bedrock::DataSource", { KnowledgeBaseId: { - 'Fn::GetAtt': [Match.anyValue(), 'KnowledgeBaseId'], + "Fn::GetAtt": [Match.anyValue(), "KnowledgeBaseId"], }, - Name: 'TestDataSource', + Name: "TestDataSource", DataSourceConfiguration: { S3Configuration: { BucketArn: { - 'Fn::GetAtt': [Match.anyValue(), 'Arn'], + "Fn::GetAtt": [Match.anyValue(), "Arn"], }, }, }, }); }); - test('Default chunking', () => { - new bedrock.S3DataSource(stack, 'TestDataSource', { + test("Default chunking", () => { + new bedrock.S3DataSource(stack, "TestDataSource", { bucket, knowledgeBase: kb, - dataSourceName: 'TestDataSource', + dataSourceName: "TestDataSource", chunkingStrategy: bedrock.ChunkingStrategy.DEFAULT, }); - Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::DataSource', { - VectorIngestionConfiguration: - { + Template.fromStack(stack).hasResourceProperties("AWS::Bedrock::DataSource", { + VectorIngestionConfiguration: { ChunkingConfiguration: { - ChunkingStrategy: 'FIXED_SIZE', + ChunkingStrategy: "FIXED_SIZE", FixedSizeChunkingConfiguration: { MaxTokens: 300, OverlapPercentage: 20, @@ -79,23 +76,21 @@ describe('S3 Data Source', () => { }); }); - test('Fixed size chunking', () => { - new bedrock.S3DataSource(stack, 'TestDataSource', { + test("Fixed size chunking", () => { + new bedrock.S3DataSource(stack, "TestDataSource", { bucket, knowledgeBase: kb, - dataSourceName: 'TestDataSource', + dataSourceName: "TestDataSource", chunkingStrategy: bedrock.ChunkingStrategy.fixedSize({ maxTokens: 1024, overlapPercentage: 20, }), }); - Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::DataSource', { - - VectorIngestionConfiguration: - { + Template.fromStack(stack).hasResourceProperties("AWS::Bedrock::DataSource", { + VectorIngestionConfiguration: { ChunkingConfiguration: { - ChunkingStrategy: 'FIXED_SIZE', + ChunkingStrategy: "FIXED_SIZE", FixedSizeChunkingConfiguration: { MaxTokens: 1024, OverlapPercentage: 20, @@ -105,35 +100,33 @@ describe('S3 Data Source', () => { }); }); - test('No chunking', () => { - new bedrock.S3DataSource(stack, 'TestDataSource', { + test("No chunking", () => { + new bedrock.S3DataSource(stack, "TestDataSource", { bucket, knowledgeBase: kb, - dataSourceName: 'TestDataSource', + dataSourceName: "TestDataSource", chunkingStrategy: bedrock.ChunkingStrategy.NONE, }); - Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::DataSource', { - VectorIngestionConfiguration: - { - ChunkingConfiguration: - { ChunkingStrategy: 'NONE' }, + Template.fromStack(stack).hasResourceProperties("AWS::Bedrock::DataSource", { + VectorIngestionConfiguration: { + ChunkingConfiguration: { ChunkingStrategy: "NONE" }, }, }); }); - test('Semantic chunking - default', () => { - new bedrock.S3DataSource(stack, 'TestDataSource', { + test("Semantic chunking - default", () => { + new bedrock.S3DataSource(stack, "TestDataSource", { bucket, knowledgeBase: kb, - dataSourceName: 'TestDataSource', + dataSourceName: "TestDataSource", chunkingStrategy: bedrock.ChunkingStrategy.SEMANTIC, }); - Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::DataSource', { + Template.fromStack(stack).hasResourceProperties("AWS::Bedrock::DataSource", { VectorIngestionConfiguration: { ChunkingConfiguration: { - ChunkingStrategy: 'SEMANTIC', + ChunkingStrategy: "SEMANTIC", SemanticChunkingConfiguration: { MaxTokens: 300, BufferSize: 0, @@ -144,11 +137,11 @@ describe('S3 Data Source', () => { }); }); - test('Semantic chunking', () => { - new bedrock.S3DataSource(stack, 'TestDataSource', { + test("Semantic chunking", () => { + new bedrock.S3DataSource(stack, "TestDataSource", { bucket, knowledgeBase: kb, - dataSourceName: 'TestDataSource', + dataSourceName: "TestDataSource", chunkingStrategy: bedrock.ChunkingStrategy.semantic({ maxTokens: 1024, bufferSize: 1, @@ -156,10 +149,10 @@ describe('S3 Data Source', () => { }), }); - Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::DataSource', { + Template.fromStack(stack).hasResourceProperties("AWS::Bedrock::DataSource", { VectorIngestionConfiguration: { ChunkingConfiguration: { - ChunkingStrategy: 'SEMANTIC', + ChunkingStrategy: "SEMANTIC", SemanticChunkingConfiguration: { MaxTokens: 1024, BufferSize: 1, @@ -170,18 +163,18 @@ describe('S3 Data Source', () => { }); }); - test('Hierarchical chunking - default', () => { - new bedrock.S3DataSource(stack, 'TestDataSource', { + test("Hierarchical chunking - default", () => { + new bedrock.S3DataSource(stack, "TestDataSource", { bucket, knowledgeBase: kb, - dataSourceName: 'TestDataSource', + dataSourceName: "TestDataSource", chunkingStrategy: bedrock.ChunkingStrategy.HIERARCHICAL_TITAN, }); - Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::DataSource', { + Template.fromStack(stack).hasResourceProperties("AWS::Bedrock::DataSource", { VectorIngestionConfiguration: { ChunkingConfiguration: { - ChunkingStrategy: 'HIERARCHICAL', + ChunkingStrategy: "HIERARCHICAL", HierarchicalChunkingConfiguration: { LevelConfigurations: [ { MaxTokens: 1500 }, // Parent max tokens @@ -194,11 +187,11 @@ describe('S3 Data Source', () => { }); }); - test('Hierarchical chunking - custom', () => { - new bedrock.S3DataSource(stack, 'TestDataSource', { + test("Hierarchical chunking - custom", () => { + new bedrock.S3DataSource(stack, "TestDataSource", { bucket, knowledgeBase: kb, - dataSourceName: 'TestDataSource', + dataSourceName: "TestDataSource", chunkingStrategy: bedrock.ChunkingStrategy.hierarchical({ maxParentTokenSize: 1024, maxChildTokenSize: 256, @@ -206,10 +199,10 @@ describe('S3 Data Source', () => { }), }); - Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::DataSource', { + Template.fromStack(stack).hasResourceProperties("AWS::Bedrock::DataSource", { VectorIngestionConfiguration: { ChunkingConfiguration: { - ChunkingStrategy: 'HIERARCHICAL', + ChunkingStrategy: "HIERARCHICAL", HierarchicalChunkingConfiguration: { LevelConfigurations: [ { MaxTokens: 1024 }, // Parent max tokens @@ -222,26 +215,24 @@ describe('S3 Data Source', () => { }); }); - test('FM parsing', () => { - new bedrock.S3DataSource(stack, 'TestDataSource', { + test("FM parsing", () => { + new bedrock.S3DataSource(stack, "TestDataSource", { bucket, knowledgeBase: kb, - dataSourceName: 'TestDataSource', + dataSourceName: "TestDataSource", parsingStrategy: bedrock.ParsingStategy.foundationModel({ - parsingModel: FoundationModel.fromFoundationModelId(stack, 'model', - FoundationModelIdentifier.ANTHROPIC_CLAUDE_3_SONNET_20240229_V1_0, - ), + parsingModel: foundationModels.BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0, }), }); - Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::DataSource', { + Template.fromStack(stack).hasResourceProperties("AWS::Bedrock::DataSource", { VectorIngestionConfiguration: { ParsingConfiguration: { - ParsingStrategy: 'BEDROCK_FOUNDATION_MODEL', + ParsingStrategy: "BEDROCK_FOUNDATION_MODEL", BedrockFoundationModelConfiguration: { ModelArn: Match.anyValue(), ParsingPrompt: { - ParsingPromptText: Match.stringLikeRegexp('Transcribe the text content.*'), + ParsingPromptText: Match.stringLikeRegexp("Transcribe the text content.*"), }, }, }, @@ -249,20 +240,20 @@ describe('S3 Data Source', () => { }); }); - test('Lambda Transformation', () => { + test("Lambda Transformation", () => { // WHEN - const bucket2 = new s3.Bucket(stack, 'mybucket', { - bucketName: 'mybucketname', + const bucket2 = new s3.Bucket(stack, "mybucket", { + bucketName: "mybucketname", }); - const lambdaFunction = new Function(stack, 'myFunction', { + const lambdaFunction = new Function(stack, "myFunction", { code: Code.fromInline('exports.handler = function(event, ctx, cb) { return cb(null, "hello"); }'), - handler: 'index.handler', + handler: "index.handler", runtime: Runtime.PYTHON_3_11, }); - new bedrock.S3DataSource(stack, 'TestDataSource', { + new bedrock.S3DataSource(stack, "TestDataSource", { bucket, knowledgeBase: kb, - dataSourceName: 'TestDataSource', + dataSourceName: "TestDataSource", customTransformation: bedrock.CustomTransformation.lambda({ lambdaFunction, s3BucketUri: `s3://${bucket2.bucketName}/chunkprocessor`, @@ -270,19 +261,21 @@ describe('S3 Data Source', () => { }); // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::DataSource', { + Template.fromStack(stack).hasResourceProperties("AWS::Bedrock::DataSource", { VectorIngestionConfiguration: { CustomTransformationConfiguration: { - Transformations: [{ - StepToApply: 'POST_CHUNKING', - TransformationFunction: { - TransformationLambdaConfiguration: { - LambdaArn: { - 'Fn::GetAtt': [Match.anyValue(), 'Arn'], + Transformations: [ + { + StepToApply: "POST_CHUNKING", + TransformationFunction: { + TransformationLambdaConfiguration: { + LambdaArn: { + "Fn::GetAtt": [Match.anyValue(), "Arn"], + }, }, }, }, - }], + ], IntermediateStorage: { S3Location: { URI: Match.anyValue(), @@ -291,8 +284,5 @@ describe('S3 Data Source', () => { }, }, }); - }); - - -}); \ No newline at end of file +}); diff --git a/test/cdk-lib/bedrock/inference-profile.test.ts b/test/cdk-lib/bedrock/inference-profile.test.ts index b97ed491..a4504326 100644 --- a/test/cdk-lib/bedrock/inference-profile.test.ts +++ b/test/cdk-lib/bedrock/inference-profile.test.ts @@ -16,6 +16,82 @@ import { CfnApplicationInferenceProfile } from "aws-cdk-lib/aws-bedrock"; import { AwsSolutionsChecks } from "cdk-nag"; import * as bedrock from "../../../src/cdk-lib/bedrock"; +describe("CDK-Created-Cross-Region-Inference-Profile", () => { + let stack: cdk.Stack; + + beforeEach(() => { + const app = new cdk.App(); + cdk.Aspects.of(app).add(new AwsSolutionsChecks()); + stack = new cdk.Stack(app, "TestStack"); + }); + + test("Basic Creation", () => { + new bedrock.CrossRegionInferenceProfile(stack, "TestAIP", { + geoRegion: bedrock.CrossRegionInferenceProfileRegion.EU, + model: bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0, + }); + + Template.fromStack(stack).hasResourceProperties("AWS::Bedrock::ApplicationInferenceProfile", { + InferenceProfileName: "TestAIP", + Description: "This is a test application inf profile", + ModelSource: { + CopyFrom: { + "Fn::Join": [ + "", + [ + "arn:aws:bedrock:", + { + Ref: "AWS::Region", + }, + "::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0", + ], + ], + }, + }, + Tags: [ + { + Key: "test-key", + Value: "test-value", + }, + ], + }); + }); + + test("Basic Creation with a system defined inference profile", () => { + new bedrock.ApplicationInferenceProfile(stack, "TestAIPSystem", { + inferenceProfileName: "TestAIPSystem", + modelSource: bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_3_5_SONNET_V2_0, + }); + + Template.fromStack(stack).hasResourceProperties("AWS::Bedrock::ApplicationInferenceProfile", { + InferenceProfileName: "TestAIPSystem", + Description: Match.absent(), + ModelSource: { + CopyFrom: "arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0", + }, + }); + }); + + test("Basic Creation", () => { + new bedrock.ApplicationInferenceProfile(stack, "TestAIPSystem", { + inferenceProfileName: "TestAIPSystem", + modelSource: new bedrock.CrossRegionInferenceProfile(stack, "CrossRegion", { + model: bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_3_5_SONNET_V2_0, + geoRegion: bedrock.CrossRegionInferenceProfileRegion.EU, + }), + tags: [{ key: "project", value: "test" }], + }); + + Template.fromStack(stack).hasResourceProperties("AWS::Bedrock::ApplicationInferenceProfile", { + InferenceProfileName: "TestAIPSystem", + Description: Match.absent(), + ModelSource: { + CopyFrom: "arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0", + }, + }); + }); +}); + describe("CDK-Created-Application-Inference-Profile", () => { let stack: cdk.Stack; @@ -73,6 +149,25 @@ describe("CDK-Created-Application-Inference-Profile", () => { }, }); }); + + test("Basic Creation", () => { + new bedrock.ApplicationInferenceProfile(stack, "TestAIPSystem", { + inferenceProfileName: "TestAIPSystem", + modelSource: new bedrock.CrossRegionInferenceProfile(stack, "CrossRegion", { + model: bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_3_5_SONNET_V2_0, + geoRegion: bedrock.CrossRegionInferenceProfileRegion.EU, + }), + tags: [{ key: "project", value: "test" }], + }); + + Template.fromStack(stack).hasResourceProperties("AWS::Bedrock::ApplicationInferenceProfile", { + InferenceProfileName: "TestAIPSystem", + Description: Match.absent(), + ModelSource: { + CopyFrom: "arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0", + }, + }); + }); }); describe("Imported-ApplicationInferenceProfile", () => { From c57cf63bc0f7bb2e813d7c6e0aa9c7db032e842a Mon Sep 17 00:00:00 2001 From: Rafael Mosca Date: Fri, 15 Nov 2024 19:12:29 +0100 Subject: [PATCH 11/22] feat(bedrock): add IInvokable pt2 --- .../application-inference-profile.ts | 4 +-- src/cdk-lib/bedrock/models.ts | 7 ++++- test/integ/inference-profiles.test.ts | 30 +++++++++++++++++++ 3 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 test/integ/inference-profiles.test.ts diff --git a/src/cdk-lib/bedrock/inference-profiles/application-inference-profile.ts b/src/cdk-lib/bedrock/inference-profiles/application-inference-profile.ts index a1b8508d..15f347f3 100644 --- a/src/cdk-lib/bedrock/inference-profiles/application-inference-profile.ts +++ b/src/cdk-lib/bedrock/inference-profiles/application-inference-profile.ts @@ -43,7 +43,7 @@ export interface ApplicationInferenceProfileProps { * the cross region (system-defined) inference profile that you choose. * Usage and costs for requests made to the Regions in the inference profile will be tracked. */ - readonly modelSource: bedrock.IModel; + readonly modelSource: IInvokable; /** * A list of tags associated with the inference profile. * */ @@ -157,7 +157,7 @@ export class ApplicationInferenceProfile extends InferenceProfileBase implements description: props.description, inferenceProfileName: props.inferenceProfileName, modelSource: { - copyFrom: props.modelSource.modelArn, + copyFrom: props.modelSource.invokableArn, }, tags: props.tags, }); diff --git a/src/cdk-lib/bedrock/models.ts b/src/cdk-lib/bedrock/models.ts index 7514d4c8..0b5b813b 100644 --- a/src/cdk-lib/bedrock/models.ts +++ b/src/cdk-lib/bedrock/models.ts @@ -15,9 +15,14 @@ import { Arn, ArnFormat, Aws, Stack } from "aws-cdk-lib"; import { IModel } from "aws-cdk-lib/aws-bedrock"; import { IConstruct } from "constructs"; +/** + * Represents an Amazon Bedrock abstraction on which you can + * run the `Invoke` API. This can be a Foundational Model, + * a Custom Model, or an Inference Profile. + */ export interface IInvokable { /** - * The ARN of the Bedrock invokable object. + * The ARN of the Bedrock invokable abstraction. */ readonly invokableArn: string; } diff --git a/test/integ/inference-profiles.test.ts b/test/integ/inference-profiles.test.ts new file mode 100644 index 00000000..5e416bc5 --- /dev/null +++ b/test/integ/inference-profiles.test.ts @@ -0,0 +1,30 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance + * with the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES + * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ +import * as integ from "@aws-cdk/integ-tests-alpha"; +import * as cdk from "aws-cdk-lib"; + +const app = new cdk.App(); +const stack = new cdk.Stack(app, "aws-cdk-bedrock-guardrails-integ-test"); + +new integ.IntegTest(app, "ServiceTest", { + testCases: [stack], + cdkCommandOptions: { + destroy: { + args: { + force: true, + }, + }, + }, +}); + +app.synth(); From 40609a2951317d700013f1e15d63eea17ac54093 Mon Sep 17 00:00:00 2001 From: krokoko Date: Fri, 15 Nov 2024 12:17:52 -0600 Subject: [PATCH 12/22] chore(deps): bring back cdk v.2.166 due to changes requiring more testing --- .projen/deps.json | 4 ++-- .projenrc.ts | 2 +- CHANGELOG.md | 2 +- DEVELOPER_GUIDE.md | 2 +- apidocs/interfaces/DockerLambdaCustomProps.md | 2 +- package.json | 6 +++--- src/common/props/DockerLambdaCustomProps.ts | 2 +- yarn.lock | 16 ++++++++-------- 8 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.projen/deps.json b/.projen/deps.json index 5a108f67..f367a4fe 100644 --- a/.projen/deps.json +++ b/.projen/deps.json @@ -6,7 +6,7 @@ }, { "name": "@aws-cdk/integ-tests-alpha", - "version": "2.167.0-alpha.0", + "version": "2.166.0-alpha.0", "type": "build" }, { @@ -137,7 +137,7 @@ }, { "name": "aws-cdk-lib", - "version": "^2.167.0", + "version": "^2.166.0", "type": "peer" }, { diff --git a/.projenrc.ts b/.projenrc.ts index 93b5ad6e..29a33cc8 100644 --- a/.projenrc.ts +++ b/.projenrc.ts @@ -30,7 +30,7 @@ import { const GITHUB_USER = 'awslabs'; const PUBLICATION_NAMESPACE = 'cdklabs'; const PROJECT_NAME = 'generative-ai-cdk-constructs'; -const CDK_VERSION: string = '2.167.0'; +const CDK_VERSION: string = '2.166.0'; function camelCaseIt(input: string): string { // Hypens and dashes to spaces and then CamelCase... diff --git a/CHANGELOG.md b/CHANGELOG.md index f563868d..6a36dff0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # CDK Generative AI Constructs V0.1.282 (2024-11-18) -Based on CDK library version 2.167.0 +Based on CDK library version 2.166.0.0 # CDK Generative AI Constructs V0.1.273 (2024-10-15) diff --git a/DEVELOPER_GUIDE.md b/DEVELOPER_GUIDE.md index 38f66a84..9118b64b 100644 --- a/DEVELOPER_GUIDE.md +++ b/DEVELOPER_GUIDE.md @@ -16,7 +16,7 @@ Default output format [None]: json ``` - [Node](https://nodejs.org/en) >= v20.9.0 -- [AWS CDK](https://github.com/aws/aws-cdk/releases/tag/v2.167.0) >= 2.167.0 +- [AWS CDK](https://github.com/aws/aws-cdk/releases/tag/v2.166.0) >= 2.166.0 - [Python](https://www.python.org/downloads/) >=3.9 - [Projen](https://github.com/projen/projen) >= 0.78.8 - [Yarn](https://classic.yarnpkg.com/lang/en/docs/cli/install/) >= 1.22.19 diff --git a/apidocs/interfaces/DockerLambdaCustomProps.md b/apidocs/interfaces/DockerLambdaCustomProps.md index 21a1f797..51aa9785 100644 --- a/apidocs/interfaces/DockerLambdaCustomProps.md +++ b/apidocs/interfaces/DockerLambdaCustomProps.md @@ -669,7 +669,7 @@ stable > `readonly` `optional` **snapStart**: `SnapStartConf` Enable SnapStart for Lambda Function. -SnapStart is currently supported for Java 11, Java 17, Python 3.12, Python 3.13, and .NET 8 runtime +SnapStart is currently supported only for Java 11, 17 runtime #### Default diff --git a/package.json b/package.json index 5d23b5aa..b6446e80 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ }, "devDependencies": { "@aws-cdk/assert": "^2.68.0", - "@aws-cdk/integ-tests-alpha": "2.167.0-alpha.0", + "@aws-cdk/integ-tests-alpha": "2.166.0-alpha.0", "@commitlint/config-conventional": "^18.6.3", "@mrgrain/jsii-struct-builder": "^0.7.43", "@types/jest": "^29.5.14", @@ -63,7 +63,7 @@ "@typescript-eslint/eslint-plugin": "^7", "@typescript-eslint/parser": "^7", "aws-cdk": "^2", - "aws-cdk-lib": "2.167.0", + "aws-cdk-lib": "2.166.0", "aws-sdk-mock": "^5.9.0", "commitlint": "^18.6.1", "constructs": "10.3.0", @@ -88,7 +88,7 @@ "typescript": "^5.6.3" }, "peerDependencies": { - "aws-cdk-lib": "^2.167.0", + "aws-cdk-lib": "^2.166.0", "constructs": "^10.3.0" }, "dependencies": { diff --git a/src/common/props/DockerLambdaCustomProps.ts b/src/common/props/DockerLambdaCustomProps.ts index 2f691ac8..2523169a 100644 --- a/src/common/props/DockerLambdaCustomProps.ts +++ b/src/common/props/DockerLambdaCustomProps.ts @@ -29,7 +29,7 @@ export interface DockerLambdaCustomProps { readonly systemLogLevelV2?: aws_lambda.SystemLogLevel; /** * Enable SnapStart for Lambda Function. - * SnapStart is currently supported for Java 11, Java 17, Python 3.12, Python 3.13, and .NET 8 runtime + * SnapStart is currently supported only for Java 11, 17 runtime * @default - No snapstart * @stability stable */ diff --git a/yarn.lock b/yarn.lock index 3c796e99..0d412088 100644 --- a/yarn.lock +++ b/yarn.lock @@ -60,10 +60,10 @@ string-width "^4.2.3" table "^6.8.1" -"@aws-cdk/integ-tests-alpha@2.167.0-alpha.0": - version "2.167.0-alpha.0" - resolved "https://registry.yarnpkg.com/@aws-cdk/integ-tests-alpha/-/integ-tests-alpha-2.167.0-alpha.0.tgz#a8d3dc8d2bdb5900fd713d13c49a28d3d8e2556b" - integrity sha512-3C3T/ZeJouGZYIAxhMI1DIx6aQlbb6Vid+nYouyEtFjHl0dQnsmZU7XLAsUdtUZxl2+HuDjkuG9Akf3o1iDC0Q== +"@aws-cdk/integ-tests-alpha@2.166.0-alpha.0": + version "2.166.0-alpha.0" + resolved "https://registry.yarnpkg.com/@aws-cdk/integ-tests-alpha/-/integ-tests-alpha-2.166.0-alpha.0.tgz#fc82a90c422cd0ff90ee4b3f72026b6eb900cd1b" + integrity sha512-ksM64XQP0FzzGxmVFQQDF8JIJKJpcfUoFWTvRghDMDNq8IBi/KsP4/gXpHDyl4jtS58EPOMBpsy0SRCFyOCVvw== "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.25.9", "@babel/code-frame@^7.26.0": version "7.26.2" @@ -1436,10 +1436,10 @@ available-typed-arrays@^1.0.7: dependencies: possible-typed-array-names "^1.0.0" -aws-cdk-lib@2.167.0: - version "2.167.0" - resolved "https://registry.yarnpkg.com/aws-cdk-lib/-/aws-cdk-lib-2.167.0.tgz#7f2a8534a5054155e3a03f9d695ef5b8a60c14a8" - integrity sha512-q8bHxUUnMGfHe4TWQHYUu4eqdy9qkEWuml3vOnZINF3l9XdKOo/S5grsyVzFAjjBjwCH8zAxKicNT0uhwBjqLg== +aws-cdk-lib@2.166.0: + version "2.166.0" + resolved "https://registry.yarnpkg.com/aws-cdk-lib/-/aws-cdk-lib-2.166.0.tgz#279343451cc9391d52d77121e2a3feb2c756e3be" + integrity sha512-FAsIz/CpczbMrcShgvTWNp3kcGN6IDojJWNLqHioTRsTekcyN3OPmKvQJXUNWL0fnhTd8biFXC2esg6kM19xZw== dependencies: "@aws-cdk/asset-awscli-v1" "^2.2.208" "@aws-cdk/asset-kubectl-v20" "^2.1.3" From 7509c3cde695ecf3f467b27e64787b12a27f0784 Mon Sep 17 00:00:00 2001 From: Rafael Mosca Date: Fri, 15 Nov 2024 19:48:33 +0100 Subject: [PATCH 13/22] fix(bedrock): add test case --- .gitignore | 9 + .npmignore | 2 + .projen/tasks.json | 69 +++++++ package.json | 5 + src/cdk-lib/bedrock/agent.ts | 130 +++++++------- src/cdk-lib/bedrock/data-sources/parsing.ts | 2 +- .../bedrock/inference-profiles/common.ts | 4 +- .../cross-region-inference-profile.ts | 28 ++- src/cdk-lib/bedrock/models.ts | 6 +- src/common/props/DockerLambdaCustomProps.ts | 2 +- ...efaultTestDeployAssertE49B1ECE.assets.json | 19 ++ ...aultTestDeployAssertE49B1ECE.template.json | 36 ++++ ...-bedrock-guardrails-integ-test.assets.json | 20 +++ ...edrock-guardrails-integ-test.template.json | 170 ++++++++++++++++++ .../integ.json | 19 ++ ...es.test.ts => inference-profiles.integ.ts} | 22 ++- 16 files changed, 466 insertions(+), 77 deletions(-) create mode 100644 test/integ/inference-profiles.integ.snapshot/ServiceTestDefaultTestDeployAssertE49B1ECE.assets.json create mode 100644 test/integ/inference-profiles.integ.snapshot/ServiceTestDefaultTestDeployAssertE49B1ECE.template.json create mode 100644 test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.assets.json create mode 100644 test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.template.json create mode 100644 test/integ/inference-profiles.integ.snapshot/integ.json rename test/integ/{inference-profiles.test.ts => inference-profiles.integ.ts} (62%) diff --git a/.gitignore b/.gitignore index 249ee8ac..b22a12e5 100644 --- a/.gitignore +++ b/.gitignore @@ -56,6 +56,15 @@ junit.xml !/.eslintrc.json .jsii tsconfig.json +test/integ/.tmp +test/integ/inference-profiles.integ.snapshot/asset.* +test/integ/inference-profiles.integ.snapshot/**/asset.* +test/integ/inference-profiles.integ.snapshot/cdk.out +test/integ/inference-profiles.integ.snapshot/**/cdk.out +test/integ/inference-profiles.integ.snapshot/manifest.json +test/integ/inference-profiles.integ.snapshot/**/manifest.json +test/integ/inference-profiles.integ.snapshot/tree.json +test/integ/inference-profiles.integ.snapshot/**/tree.json test/patterns/gen-ai/aws-aoss-cw-dashboard/integ-tests/.tmp test/patterns/gen-ai/aws-aoss-cw-dashboard/integ-tests/aws-aoss-cw-dashboard.integ.snapshot/asset.* test/patterns/gen-ai/aws-aoss-cw-dashboard/integ-tests/aws-aoss-cw-dashboard.integ.snapshot/**/asset.* diff --git a/.npmignore b/.npmignore index 1f169094..19d6a6b9 100644 --- a/.npmignore +++ b/.npmignore @@ -22,6 +22,8 @@ dist tsconfig.tsbuildinfo /.eslintrc.json !.jsii +test/integ/.tmp +test/integ/inference-profiles.integ.snapshot test/patterns/gen-ai/aws-aoss-cw-dashboard/integ-tests/.tmp test/patterns/gen-ai/aws-aoss-cw-dashboard/integ-tests/aws-aoss-cw-dashboard.integ.snapshot test/patterns/gen-ai/aws-llama-index-data-loader/integ-tests/.tmp diff --git a/.projen/tasks.json b/.projen/tasks.json index ed8c64df..f06dde3b 100644 --- a/.projen/tasks.json +++ b/.projen/tasks.json @@ -290,10 +290,76 @@ } ] }, + "integ:inference-profiles:assert": { + "name": "integ:inference-profiles:assert", + "description": "assert the snapshot of integration test 'inference-profiles'", + "steps": [ + { + "exec": "[ -d \"test/integ/inference-profiles.integ.snapshot\" ] || (echo \"No snapshot available for integration test 'inference-profiles'. Run 'projen integ:inference-profiles:deploy' to capture.\" && exit 1)" + }, + { + "exec": "cdk synth --app \"ts-node -P tsconfig.dev.json test/integ/inference-profiles.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata -o test/integ/.tmp/inference-profiles.integ/assert.cdk.out > /dev/null" + }, + { + "exec": "diff -r -x asset.* -x cdk.out -x manifest.json -x tree.json test/integ/inference-profiles.integ.snapshot/ test/integ/.tmp/inference-profiles.integ/assert.cdk.out/" + } + ] + }, + "integ:inference-profiles:deploy": { + "name": "integ:inference-profiles:deploy", + "description": "deploy integration test 'inference-profiles' and capture snapshot", + "steps": [ + { + "exec": "rm -fr test/integ/.tmp/inference-profiles.integ/deploy.cdk.out" + }, + { + "exec": "cdk deploy --app \"ts-node -P tsconfig.dev.json test/integ/inference-profiles.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata '**' --require-approval=never -o test/integ/.tmp/inference-profiles.integ/deploy.cdk.out" + }, + { + "exec": "rm -fr test/integ/inference-profiles.integ.snapshot" + }, + { + "exec": "mv test/integ/.tmp/inference-profiles.integ/deploy.cdk.out test/integ/inference-profiles.integ.snapshot" + }, + { + "spawn": "integ:inference-profiles:destroy" + } + ] + }, + "integ:inference-profiles:destroy": { + "name": "integ:inference-profiles:destroy", + "description": "destroy integration test 'inference-profiles'", + "steps": [ + { + "exec": "cdk destroy --app test/integ/inference-profiles.integ.snapshot '**' --no-version-reporting" + } + ] + }, + "integ:inference-profiles:snapshot": { + "name": "integ:inference-profiles:snapshot", + "description": "update snapshot for integration test \"inference-profiles\"", + "steps": [ + { + "exec": "cdk synth --app \"ts-node -P tsconfig.dev.json test/integ/inference-profiles.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata -o test/integ/inference-profiles.integ.snapshot > /dev/null" + } + ] + }, + "integ:inference-profiles:watch": { + "name": "integ:inference-profiles:watch", + "description": "watch integration test 'inference-profiles' (without updating snapshots)", + "steps": [ + { + "exec": "cdk watch --app \"ts-node -P tsconfig.dev.json test/integ/inference-profiles.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata '**' -o test/integ/.tmp/inference-profiles.integ/deploy.cdk.out" + } + ] + }, "integ:snapshot-all": { "name": "integ:snapshot-all", "description": "update snapshot for all integration tests", "steps": [ + { + "spawn": "integ:inference-profiles:snapshot" + }, { "spawn": "integ:aws-aoss-cw-dashboard:snapshot" }, @@ -439,6 +505,9 @@ { "spawn": "eslint" }, + { + "spawn": "integ:inference-profiles:assert" + }, { "spawn": "integ:aws-aoss-cw-dashboard:assert" }, diff --git a/package.json b/package.json index 4f5486f6..60bf2cc0 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,11 @@ "integ:aws-llama-index-data-loader:destroy": "npx projen integ:aws-llama-index-data-loader:destroy", "integ:aws-llama-index-data-loader:snapshot": "npx projen integ:aws-llama-index-data-loader:snapshot", "integ:aws-llama-index-data-loader:watch": "npx projen integ:aws-llama-index-data-loader:watch", + "integ:inference-profiles:assert": "npx projen integ:inference-profiles:assert", + "integ:inference-profiles:deploy": "npx projen integ:inference-profiles:deploy", + "integ:inference-profiles:destroy": "npx projen integ:inference-profiles:destroy", + "integ:inference-profiles:snapshot": "npx projen integ:inference-profiles:snapshot", + "integ:inference-profiles:watch": "npx projen integ:inference-profiles:watch", "integ:snapshot-all": "npx projen integ:snapshot-all", "package": "npx projen package", "package-all": "npx projen package-all", diff --git a/src/cdk-lib/bedrock/agent.ts b/src/cdk-lib/bedrock/agent.ts index 9b6595b9..67465c3a 100644 --- a/src/cdk-lib/bedrock/agent.ts +++ b/src/cdk-lib/bedrock/agent.ts @@ -11,27 +11,27 @@ * and limitations under the License. */ -import * as cdk from 'aws-cdk-lib'; -import { aws_bedrock as bedrock } from 'aws-cdk-lib'; -import * as iam from 'aws-cdk-lib/aws-iam'; -import * as kms from 'aws-cdk-lib/aws-kms'; -import { Construct } from 'constructs'; - -import { AgentActionGroup } from './agent-action-group'; -import { AgentAlias } from './agent-alias'; -import { IGuardrail } from './guardrails/guardrails'; -import { KnowledgeBase } from './knowledge-base'; -import { BedrockFoundationModel } from './models'; -import { generatePhysicalNameV2 } from '../../common/helpers/utils'; +import * as cdk from "aws-cdk-lib"; +import { aws_bedrock as bedrock } from "aws-cdk-lib"; +import * as iam from "aws-cdk-lib/aws-iam"; +import * as kms from "aws-cdk-lib/aws-kms"; +import { Construct } from "constructs"; + +import { AgentActionGroup } from "./agent-action-group"; +import { AgentAlias } from "./agent-alias"; +import { IGuardrail } from "./guardrails/guardrails"; +import { KnowledgeBase } from "./knowledge-base"; +import { IInvokable } from "./models"; +import { generatePhysicalNameV2 } from "../../common/helpers/utils"; /** * The step in the agent sequence that this prompt configuration applies to. */ export enum PromptType { - PRE_PROCESSING = 'PRE_PROCESSING', - ORCHESTRATION = 'ORCHESTRATION', - POST_PROCESSING = 'POST_PROCESSING', - KNOWLEDGE_BASE_RESPONSE_GENERATION = 'KNOWLEDGE_BASE_RESPONSE_GENERATION', + PRE_PROCESSING = "PRE_PROCESSING", + ORCHESTRATION = "ORCHESTRATION", + POST_PROCESSING = "POST_PROCESSING", + KNOWLEDGE_BASE_RESPONSE_GENERATION = "KNOWLEDGE_BASE_RESPONSE_GENERATION", } /** @@ -42,8 +42,8 @@ export enum PromptType { * with the ARN of a Lambda function. */ export enum ParserMode { - DEFAULT = 'DEFAULT', - OVERRIDDEN = 'OVERRIDDEN', + DEFAULT = "DEFAULT", + OVERRIDDEN = "OVERRIDDEN", } /** @@ -53,8 +53,8 @@ export enum ParserMode { * uses a default prompt template. */ export enum PromptCreationMode { - DEFAULT = 'DEFAULT', - OVERRIDDEN = 'OVERRIDDEN', + DEFAULT = "DEFAULT", + OVERRIDDEN = "OVERRIDDEN", } /** @@ -68,8 +68,8 @@ export enum PromptCreationMode { * POST_PROCESSING – DISABLED */ export enum PromptState { - ENABLED = 'ENABLED', - DISABLED = 'DISABLED', + ENABLED = "ENABLED", + DISABLED = "DISABLED", } /** Details about the guardrail associated with the agent. */ @@ -212,7 +212,7 @@ export interface AgentProps { /** * The Bedrock text foundation model for the agent to use. */ - readonly foundationModel: BedrockFoundationModel; + readonly model: IInvokable; /** * The name of the agent. * @@ -390,54 +390,54 @@ export class Agent extends Construct { super(scope, id); validatePromptOverrideConfiguration(props.promptOverrideConfiguration); - validateModel(props.foundationModel); + //validateModel(props.foundationModel); this.name = - props.name ?? generatePhysicalNameV2(this, 'bedrock-agent', { maxLength: 32, lower: true, separator: '-' }); + props.name ?? generatePhysicalNameV2(this, "bedrock-agent", { maxLength: 32, lower: true, separator: "-" }); if (props.existingRole) { this.role = props.existingRole; } else { - this.role = new iam.Role(this, 'Role', { - assumedBy: new iam.ServicePrincipal('bedrock.amazonaws.com'), - roleName: generatePhysicalNameV2(this, 'AmazonBedrockExecutionRoleForAgents_', { maxLength: 64, lower: false }), + this.role = new iam.Role(this, "Role", { + assumedBy: new iam.ServicePrincipal("bedrock.amazonaws.com"), + roleName: generatePhysicalNameV2(this, "AmazonBedrockExecutionRoleForAgents_", { maxLength: 64, lower: false }), }); this.role.assumeRolePolicy!.addStatements( new iam.PolicyStatement({ - actions: ['sts:AssumeRole'], - principals: [new iam.ServicePrincipal('bedrock.amazonaws.com')], + actions: ["sts:AssumeRole"], + principals: [new iam.ServicePrincipal("bedrock.amazonaws.com")], conditions: { StringEquals: { - 'aws:SourceAccount': cdk.Stack.of(this).account, + "aws:SourceAccount": cdk.Stack.of(this).account, }, ArnLike: { - 'aws:SourceArn': cdk.Stack.of(this).formatArn({ - service: 'bedrock', - resource: 'agent', - resourceName: '*', + "aws:SourceArn": cdk.Stack.of(this).formatArn({ + service: "bedrock", + resource: "agent", + resourceName: "*", arnFormat: cdk.ArnFormat.SLASH_RESOURCE_NAME, }), }, }, - }), + }) ); - new iam.Policy(this, 'AgentFMPolicy', { + new iam.Policy(this, "AgentFMPolicy", { roles: [this.role], statements: [ new iam.PolicyStatement({ - actions: ['bedrock:InvokeModel'], - resources: [props.foundationModel.asArn(this)], + actions: ["bedrock:InvokeModel"], + resources: [props.model.invokableArn], }), ], }); } - const agent = new bedrock.CfnAgent(this, 'Agent', { + const agent = new bedrock.CfnAgent(this, "Agent", { agentName: this.name, - foundationModel: String(props.foundationModel), + foundationModel: props.model.invokableArn, instruction: props.instruction, description: props.description, idleSessionTtlInSeconds: props.idleSessionTTL?.toSeconds(), @@ -481,11 +481,11 @@ export class Agent extends Construct { // To allow your agent to request the user for additional information // when trying to complete a task, add this action group this.addActionGroup( - new AgentActionGroup(this, 'userInputEnabledActionGroup', { - actionGroupName: 'UserInputAction', - parentActionGroupSignature: 'AMAZON.UserInput', - actionGroupState: props.enableUserInput ? 'ENABLED' : 'DISABLED', - }), + new AgentActionGroup(this, "userInputEnabledActionGroup", { + actionGroupName: "UserInputAction", + parentActionGroupSignature: "AMAZON.UserInput", + actionGroupState: props.enableUserInput ? "ENABLED" : "DISABLED", + }) ); } @@ -517,13 +517,13 @@ export class Agent extends Construct { */ public addKnowledgeBase(knowledgeBase: KnowledgeBase) { if (!knowledgeBase.instruction) { - throw new Error('Agent Knowledge Bases require instructions.'); + throw new Error("Agent Knowledge Bases require instructions."); } new iam.Policy(this, `AgentKBPolicy-${knowledgeBase.name}`, { roles: [this.role], statements: [ new iam.PolicyStatement({ - actions: ['bedrock:UpdateKnowledgeBase', 'bedrock:Retrieve'], + actions: ["bedrock:UpdateKnowledgeBase", "bedrock:Retrieve"], resources: [knowledgeBase.knowledgeBaseArn], }), ], @@ -545,8 +545,8 @@ export class Agent extends Construct { * Add action group to the agent. */ public addActionGroup(actionGroup: AgentActionGroup) { - actionGroup.actionGroupExecutor?.lambda?.addPermission('AgentLambdaInvocationPolicy', { - principal: new iam.ServicePrincipal('bedrock.amazonaws.com'), + actionGroup.actionGroupExecutor?.lambda?.addPermission("AgentLambdaInvocationPolicy", { + principal: new iam.ServicePrincipal("bedrock.amazonaws.com"), sourceArn: this.agentArn, sourceAccount: cdk.Stack.of(this).account, }); @@ -601,11 +601,11 @@ export class Agent extends Construct { * * @internal This is an internal core function and should not be called directly. */ -function validateModel(foundationModel: BedrockFoundationModel) { - if (!foundationModel.supportsAgents) { - throw new Error(`The model ${foundationModel} is not supported by Bedrock Agents.`); - } -} +// function validateModel(foundationModel: BedrockFoundationModel) { +// if (!foundationModel.supportsAgents) { +// throw new Error(`The model ${foundationModel} is not supported by Bedrock Agents.`); +// } +// } /** * Validate the inferenceConfiguration of a prompt override. @@ -614,31 +614,31 @@ function validateModel(foundationModel: BedrockFoundationModel) { */ export function validateInferenceConfiguration(inferenceConfiguration: InferenceConfiguration) { if (inferenceConfiguration.topK < 0 || inferenceConfiguration.topK > 500) { - throw new Error('topK must be between 0 and 500'); + throw new Error("topK must be between 0 and 500"); } if (!Number.isInteger(inferenceConfiguration.topK)) { - throw new Error('topK must be an integer'); + throw new Error("topK must be an integer"); } if (inferenceConfiguration.stopSequences.length > 4) { - throw new Error('stopSequences cannot contain more than 4 elements'); + throw new Error("stopSequences cannot contain more than 4 elements"); } if (inferenceConfiguration.maximumLength < 0 || inferenceConfiguration.maximumLength > 4096) { - throw new Error('maximumLength must be between 0 and 4096'); + throw new Error("maximumLength must be between 0 and 4096"); } if (!Number.isInteger(inferenceConfiguration.maximumLength)) { - throw new Error('maximumLength must be an integer'); + throw new Error("maximumLength must be an integer"); } if (inferenceConfiguration.topP < 0 || inferenceConfiguration.topP > 1) { - throw new Error('topP must be between 0 and 1'); + throw new Error("topP must be between 0 and 1"); } if (inferenceConfiguration.temperature < 0 || inferenceConfiguration.temperature > 1) { - throw new Error('temperature must be between 0 and 1'); + throw new Error("temperature must be between 0 and 1"); } } @@ -648,7 +648,7 @@ export function validateInferenceConfiguration(inferenceConfiguration: Inference * @internal This is an internal core function and should not be called directly. */ export function validatePromptOverrideConfiguration( - promptOverrideConfiguration: PromptOverrideConfiguration | undefined, + promptOverrideConfiguration: PromptOverrideConfiguration | undefined ) { if (!promptOverrideConfiguration) { return; @@ -659,7 +659,7 @@ export function validatePromptOverrideConfiguration( promptOverrideConfiguration.promptConfigurations.some((pc) => pc.parserMode !== ParserMode.OVERRIDDEN) ) { throw new Error( - 'overrideLambda can only be used if all promptConfigurations have a parserMode value of OVERRIDDEN', + "overrideLambda can only be used if all promptConfigurations have a parserMode value of OVERRIDDEN" ); } @@ -668,7 +668,7 @@ export function validatePromptOverrideConfiguration( promptOverrideConfiguration.promptConfigurations.some((pc) => pc.parserMode === ParserMode.OVERRIDDEN) ) { throw new Error( - 'At least one promptConfiguration has a parserMode value of OVERRIDDEN, but no overrideLambda is specified', + "At least one promptConfiguration has a parserMode value of OVERRIDDEN, but no overrideLambda is specified" ); } diff --git a/src/cdk-lib/bedrock/data-sources/parsing.ts b/src/cdk-lib/bedrock/data-sources/parsing.ts index 8be6dff6..56c21434 100644 --- a/src/cdk-lib/bedrock/data-sources/parsing.ts +++ b/src/cdk-lib/bedrock/data-sources/parsing.ts @@ -11,7 +11,7 @@ * and limitations under the License. */ -import { CfnDataSource, IModel } from "aws-cdk-lib/aws-bedrock"; +import { CfnDataSource } from "aws-cdk-lib/aws-bedrock"; import { PolicyStatement } from "aws-cdk-lib/aws-iam"; import { DEFAULT_PARSING_PROMPT } from "./default-parsing-prompt"; import { IInvokable } from "../models"; diff --git a/src/cdk-lib/bedrock/inference-profiles/common.ts b/src/cdk-lib/bedrock/inference-profiles/common.ts index d7845d21..e12f03f1 100644 --- a/src/cdk-lib/bedrock/inference-profiles/common.ts +++ b/src/cdk-lib/bedrock/inference-profiles/common.ts @@ -33,7 +33,7 @@ export enum InferenceProfileType { /** * Represents a ApplicationInferenceProfile, either created with CDK or imported. */ -export interface IInferenceProfile extends IResource { +export interface IInferenceProfile { /** * The ARN of the application inference profile. */ @@ -57,7 +57,7 @@ export interface IInferenceProfile extends IResource { * Abstract base class for a ApplicationInferenceProfile. * Contains methods and attributes valid for ApplicationInferenceProfiles either created with CDK or imported. */ -export abstract class InferenceProfileBase extends Resource implements IInferenceProfile { +export abstract class InferenceProfileBase extends Resource implements IInferenceProfile, IResource { /** * The ARN of the application inference profile. */ diff --git a/src/cdk-lib/bedrock/inference-profiles/cross-region-inference-profile.ts b/src/cdk-lib/bedrock/inference-profiles/cross-region-inference-profile.ts index 6ca47e24..2b556542 100644 --- a/src/cdk-lib/bedrock/inference-profiles/cross-region-inference-profile.ts +++ b/src/cdk-lib/bedrock/inference-profiles/cross-region-inference-profile.ts @@ -1,7 +1,7 @@ import { Arn, ArnFormat, Aws } from "aws-cdk-lib"; import { BedrockFoundationModel, IInvokable } from "../models"; -import { IConstruct } from "constructs"; -import { InferenceProfileBase, InferenceProfileType } from "./common"; +import { IInferenceProfile, InferenceProfileType } from "./common"; +import { Grant, IGrantable } from "aws-cdk-lib/aws-iam"; export enum CrossRegionInferenceProfileRegion { /** @@ -44,7 +44,10 @@ export interface CrossRegionInferenceProfileProps { * higher throughput and enhanced resilience during periods of peak demands. * @see https://docs.aws.amazon.com/bedrock/latest/userguide/cross-region-inference.html */ -export class CrossRegionInferenceProfile extends InferenceProfileBase implements IInvokable { +export class CrossRegionInferenceProfile implements IInvokable, IInferenceProfile { + public static fromConfig(config: CrossRegionInferenceProfileProps): CrossRegionInferenceProfile { + return new CrossRegionInferenceProfile(config); + } /** * @example 'us.anthropic.claude-3-5-sonnet-20240620-v1:0' */ @@ -54,15 +57,16 @@ export class CrossRegionInferenceProfile extends InferenceProfileBase implements */ public readonly inferenceProfileArn: string; public readonly type: InferenceProfileType; - public readonly inferenceProfileModel: IInvokable; + public readonly inferenceProfileModel: BedrockFoundationModel; /** This equals to the inferenceProfileArn property, useful just to implement IInvokable interface*/ public readonly invokableArn: string; - constructor(scope: IConstruct, id: string, props: CrossRegionInferenceProfileProps) { - super(scope, id); + private constructor(props: CrossRegionInferenceProfileProps) { if (!props.model.supportsCrossRegion) { throw new Error(`Model ${props.model.modelId} does not support cross-region inference`); } + this.type = InferenceProfileType.SYSTEM_DEFINED; + this.inferenceProfileModel = props.model; this.inferenceProfileId = `${props.geoRegion}.${props.model.modelId}`; this.inferenceProfileArn = Arn.format({ partition: Aws.PARTITION, @@ -76,4 +80,16 @@ export class CrossRegionInferenceProfile extends InferenceProfileBase implements // Needed to Implement IInvokable this.invokableArn = this.inferenceProfileArn; } + /** + * Grants appropriate permissions to use the cross-region inference profile. + * Does not grant permissions to use the model in the profile. + */ + grantProfileUsage(grantee: IGrantable): Grant { + const grant = Grant.addToPrincipal({ + grantee: grantee, + actions: ["bedrock:GetInferenceProfile", "bedrock:ListInferenceProfiles"], + resourceArns: [this.inferenceProfileArn], + }); + return grant; + } } diff --git a/src/cdk-lib/bedrock/models.ts b/src/cdk-lib/bedrock/models.ts index 0b5b813b..c70c598c 100644 --- a/src/cdk-lib/bedrock/models.ts +++ b/src/cdk-lib/bedrock/models.ts @@ -11,7 +11,7 @@ * and limitations under the License. */ -import { Arn, ArnFormat, Aws, Stack } from "aws-cdk-lib"; +import { Arn, ArnFormat, Aws } from "aws-cdk-lib"; import { IModel } from "aws-cdk-lib/aws-bedrock"; import { IConstruct } from "constructs"; @@ -202,10 +202,14 @@ export class BedrockFoundationModel implements IInvokable { * `arn:${Partition}:bedrock:${Region}::foundation-model/${ResourceId}` */ asArn(construct: IConstruct): string { + if (construct) { + } return this.modelArn; } asIModel(construct: IConstruct): IModel { + if (construct) { + } return this; } } diff --git a/src/common/props/DockerLambdaCustomProps.ts b/src/common/props/DockerLambdaCustomProps.ts index 2f691ac8..2523169a 100644 --- a/src/common/props/DockerLambdaCustomProps.ts +++ b/src/common/props/DockerLambdaCustomProps.ts @@ -29,7 +29,7 @@ export interface DockerLambdaCustomProps { readonly systemLogLevelV2?: aws_lambda.SystemLogLevel; /** * Enable SnapStart for Lambda Function. - * SnapStart is currently supported for Java 11, Java 17, Python 3.12, Python 3.13, and .NET 8 runtime + * SnapStart is currently supported only for Java 11, 17 runtime * @default - No snapstart * @stability stable */ diff --git a/test/integ/inference-profiles.integ.snapshot/ServiceTestDefaultTestDeployAssertE49B1ECE.assets.json b/test/integ/inference-profiles.integ.snapshot/ServiceTestDefaultTestDeployAssertE49B1ECE.assets.json new file mode 100644 index 00000000..4adbb7de --- /dev/null +++ b/test/integ/inference-profiles.integ.snapshot/ServiceTestDefaultTestDeployAssertE49B1ECE.assets.json @@ -0,0 +1,19 @@ +{ + "version": "38.0.1", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "ServiceTestDefaultTestDeployAssertE49B1ECE.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/test/integ/inference-profiles.integ.snapshot/ServiceTestDefaultTestDeployAssertE49B1ECE.template.json b/test/integ/inference-profiles.integ.snapshot/ServiceTestDefaultTestDeployAssertE49B1ECE.template.json new file mode 100644 index 00000000..ad9d0fb7 --- /dev/null +++ b/test/integ/inference-profiles.integ.snapshot/ServiceTestDefaultTestDeployAssertE49B1ECE.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.assets.json b/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.assets.json new file mode 100644 index 00000000..20677f80 --- /dev/null +++ b/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.assets.json @@ -0,0 +1,20 @@ +{ + "version": "38.0.1", + "files": { + "39c10ea6874f35eed43cf997c541e6b3d9cc226c39ed6a0853f5583987455851": { + "source": { + "path": "aws-cdk-bedrock-guardrails-integ-test.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-us-west-2": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-us-west-2", + "objectKey": "39c10ea6874f35eed43cf997c541e6b3d9cc226c39ed6a0853f5583987455851.json", + "region": "us-west-2", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-us-west-2" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.template.json b/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.template.json new file mode 100644 index 00000000..40d4401a --- /dev/null +++ b/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.template.json @@ -0,0 +1,170 @@ +{ + "Resources": { + "TestAgentRole522C6259": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "bedrock.amazonaws.com" + } + }, + { + "Action": "sts:AssumeRole", + "Condition": { + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + }, + "ArnLike": { + "aws:SourceArn": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":bedrock:us-west-2:", + { + "Ref": "AWS::AccountId" + }, + ":agent/*" + ] + ] + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "bedrock.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "RoleName": "AmazonBedrockExecutionRoleForAgents_awscdkbedrtTestAgent6A742A85" + } + }, + "TestAgentAgentFMPolicy7D053074": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "bedrock:InvokeModel", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":bedrock:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":inference-profile/us.anthropic.claude-3-sonnet-20240229-v1:0" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "TestAgentAgentFMPolicy7D053074", + "Roles": [ + { + "Ref": "TestAgentRole522C6259" + } + ] + } + }, + "TestAgent0DDFEE3E": { + "Type": "AWS::Bedrock::Agent", + "Properties": { + "ActionGroups": [ + { + "ActionGroupName": "UserInputAction", + "ActionGroupState": "DISABLED", + "ParentActionGroupSignature": "AMAZON.UserInput", + "SkipResourceInUseCheckOnDelete": false + } + ], + "AgentName": "test-agent", + "AgentResourceRoleArn": { + "Fn::GetAtt": [ + "TestAgentRole522C6259", + "Arn" + ] + }, + "Description": "test-description", + "FoundationModel": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":bedrock:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":inference-profile/us.anthropic.claude-3-sonnet-20240229-v1:0" + ] + ] + }, + "Instruction": "You are a test resource that needs to be very gentle and useful to the user" + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/test/integ/inference-profiles.integ.snapshot/integ.json b/test/integ/inference-profiles.integ.snapshot/integ.json new file mode 100644 index 00000000..48d7dfb3 --- /dev/null +++ b/test/integ/inference-profiles.integ.snapshot/integ.json @@ -0,0 +1,19 @@ +{ + "version": "38.0.1", + "testCases": { + "ServiceTest/DefaultTest": { + "stacks": [ + "aws-cdk-bedrock-guardrails-integ-test" + ], + "cdkCommandOptions": { + "destroy": { + "args": { + "force": true + } + } + }, + "assertionStack": "ServiceTest/DefaultTest/DeployAssert", + "assertionStackName": "ServiceTestDefaultTestDeployAssertE49B1ECE" + } + } +} \ No newline at end of file diff --git a/test/integ/inference-profiles.test.ts b/test/integ/inference-profiles.integ.ts similarity index 62% rename from test/integ/inference-profiles.test.ts rename to test/integ/inference-profiles.integ.ts index 5e416bc5..e6532e69 100644 --- a/test/integ/inference-profiles.test.ts +++ b/test/integ/inference-profiles.integ.ts @@ -12,9 +12,29 @@ */ import * as integ from "@aws-cdk/integ-tests-alpha"; import * as cdk from "aws-cdk-lib"; +import { + Agent, + BedrockFoundationModel, + CrossRegionInferenceProfile, + CrossRegionInferenceProfileRegion, +} from "../../src/cdk-lib/bedrock"; const app = new cdk.App(); -const stack = new cdk.Stack(app, "aws-cdk-bedrock-guardrails-integ-test"); +const stack = new cdk.Stack(app, "aws-cdk-bedrock-guardrails-integ-test", { + env: { + region: "us-west-2", + }, +}); + +new Agent(stack, "TestAgent", { + instruction: "You are a test bot that needs to be very gentle and useful to the user", + model: CrossRegionInferenceProfile.fromConfig({ + geoRegion: CrossRegionInferenceProfileRegion.US, + model: BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0, + }), + name: "test-agent", + description: "test-description", +}); new integ.IntegTest(app, "ServiceTest", { testCases: [stack], From bb673b4e08f1115ecdeec0f01f62383e9e224a0e Mon Sep 17 00:00:00 2001 From: Rafael Mosca Date: Fri, 15 Nov 2024 20:16:38 +0100 Subject: [PATCH 14/22] fix(bedrock): add test case --- src/cdk-lib/bedrock/agent.ts | 17 ++++------ .../application-inference-profile.ts | 27 +++++++++++++++ .../cross-region-inference-profile.ts | 11 ++++++- src/cdk-lib/bedrock/models.ts | 18 ++++++++++ ...-bedrock-guardrails-integ-test.assets.json | 4 +-- ...edrock-guardrails-integ-test.template.json | 33 +++++++++++++++++-- test/integ/inference-profiles.integ.ts | 17 ++++++++++ 7 files changed, 111 insertions(+), 16 deletions(-) diff --git a/src/cdk-lib/bedrock/agent.ts b/src/cdk-lib/bedrock/agent.ts index 67465c3a..b4a73c8e 100644 --- a/src/cdk-lib/bedrock/agent.ts +++ b/src/cdk-lib/bedrock/agent.ts @@ -340,6 +340,10 @@ export class Agent extends Construct { * The IAM role for the agent. */ public readonly role: iam.Role; + /** + * The model used by the agent. + */ + public readonly model: IInvokable; /** * The unique identifier of the agent. */ @@ -392,6 +396,7 @@ export class Agent extends Construct { //validateModel(props.foundationModel); + this.model = props.model; this.name = props.name ?? generatePhysicalNameV2(this, "bedrock-agent", { maxLength: 32, lower: true, separator: "-" }); @@ -422,18 +427,10 @@ export class Agent extends Construct { }, }) ); - - new iam.Policy(this, "AgentFMPolicy", { - roles: [this.role], - statements: [ - new iam.PolicyStatement({ - actions: ["bedrock:InvokeModel"], - resources: [props.model.invokableArn], - }), - ], - }); } + this.model.grantInvoke(this.role); + const agent = new bedrock.CfnAgent(this, "Agent", { agentName: this.name, diff --git a/src/cdk-lib/bedrock/inference-profiles/application-inference-profile.ts b/src/cdk-lib/bedrock/inference-profiles/application-inference-profile.ts index 15f347f3..d0496c18 100644 --- a/src/cdk-lib/bedrock/inference-profiles/application-inference-profile.ts +++ b/src/cdk-lib/bedrock/inference-profiles/application-inference-profile.ts @@ -15,6 +15,7 @@ import * as bedrock from "aws-cdk-lib/aws-bedrock"; import { Construct } from "constructs"; import { IInferenceProfile, InferenceProfileBase, InferenceProfileType } from "./common"; import { IInvokable } from "../models"; +import { Grant, IGrantable } from "aws-cdk-lib/aws-iam"; /****************************************************************************** * PROPS FOR NEW CONSTRUCT @@ -116,6 +117,10 @@ export class ApplicationInferenceProfile extends InferenceProfileBase implements * The unique identifier of the inference profile. */ public readonly inferenceProfileId: string; + /** + * The unique identifier of the inference profile. + */ + public readonly inferenceProfileModel: IInvokable; /** * The status of the inference profile. ACTIVE means that the inference profile is ready to be used. */ @@ -149,6 +154,7 @@ export class ApplicationInferenceProfile extends InferenceProfileBase implements constructor(scope: Construct, id: string, props: ApplicationInferenceProfileProps) { super(scope, id); + this.inferenceProfileModel = props.modelSource; this.inferenceProfileName = props.inferenceProfileName; this.type = InferenceProfileType.APPLICATION; @@ -173,4 +179,25 @@ export class ApplicationInferenceProfile extends InferenceProfileBase implements // Needed to Implement IInvokable this.invokableArn = this.inferenceProfileArn; } + + /** + * Gives the appropriate policies to invoke and use the Foundation Model. + */ + public grantInvoke(grantee: IGrantable): Grant { + this.inferenceProfileModel.grantInvoke(grantee); + return this.grantProfileUsage(grantee); + } + + /** + * Grants appropriate permissions to use the cross-region inference profile. + * Does not grant permissions to use the model in the profile. + */ + grantProfileUsage(grantee: IGrantable): Grant { + const grant = Grant.addToPrincipal({ + grantee: grantee, + actions: ["bedrock:GetInferenceProfile", "bedrock:InvokeModel"], + resourceArns: [this.inferenceProfileArn], + }); + return grant; + } } diff --git a/src/cdk-lib/bedrock/inference-profiles/cross-region-inference-profile.ts b/src/cdk-lib/bedrock/inference-profiles/cross-region-inference-profile.ts index 2b556542..2abb9665 100644 --- a/src/cdk-lib/bedrock/inference-profiles/cross-region-inference-profile.ts +++ b/src/cdk-lib/bedrock/inference-profiles/cross-region-inference-profile.ts @@ -80,6 +80,15 @@ export class CrossRegionInferenceProfile implements IInvokable, IInferenceProfil // Needed to Implement IInvokable this.invokableArn = this.inferenceProfileArn; } + + /** + * Gives the appropriate policies to invoke and use the Foundation Model. + */ + public grantInvoke(grantee: IGrantable): Grant { + this.inferenceProfileModel.grantInvoke(grantee); + return this.grantProfileUsage(grantee); + } + /** * Grants appropriate permissions to use the cross-region inference profile. * Does not grant permissions to use the model in the profile. @@ -87,7 +96,7 @@ export class CrossRegionInferenceProfile implements IInvokable, IInferenceProfil grantProfileUsage(grantee: IGrantable): Grant { const grant = Grant.addToPrincipal({ grantee: grantee, - actions: ["bedrock:GetInferenceProfile", "bedrock:ListInferenceProfiles"], + actions: ["bedrock:GetInferenceProfile", "bedrock:InvokeModel"], resourceArns: [this.inferenceProfileArn], }); return grant; diff --git a/src/cdk-lib/bedrock/models.ts b/src/cdk-lib/bedrock/models.ts index c70c598c..299a8681 100644 --- a/src/cdk-lib/bedrock/models.ts +++ b/src/cdk-lib/bedrock/models.ts @@ -13,6 +13,7 @@ import { Arn, ArnFormat, Aws } from "aws-cdk-lib"; import { IModel } from "aws-cdk-lib/aws-bedrock"; +import { Grant, IGrantable } from "aws-cdk-lib/aws-iam"; import { IConstruct } from "constructs"; /** @@ -25,6 +26,11 @@ export interface IInvokable { * The ARN of the Bedrock invokable abstraction. */ readonly invokableArn: string; + + /** + * Gives the appropriate policies to invoke and use the invokable abstraction. + */ + grantInvoke(grantee: IGrantable): Grant; } export interface BedrockFoundationModelProps { @@ -212,4 +218,16 @@ export class BedrockFoundationModel implements IInvokable { } return this; } + + /** + * Gives the appropriate policies to invoke and use the Foundation Model. + */ + public grantInvoke(grantee: IGrantable): Grant { + const grant = Grant.addToPrincipal({ + grantee: grantee, + actions: ["bedrock:InvokeModel"], + resourceArns: [this.invokableArn], + }); + return grant; + } } diff --git a/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.assets.json b/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.assets.json index 20677f80..6760607a 100644 --- a/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.assets.json +++ b/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.assets.json @@ -1,7 +1,7 @@ { "version": "38.0.1", "files": { - "39c10ea6874f35eed43cf997c541e6b3d9cc226c39ed6a0853f5583987455851": { + "3ad82f621f535ba32c03341578f617dfd8f39e99b551e31245a1aa075c64ace7": { "source": { "path": "aws-cdk-bedrock-guardrails-integ-test.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-us-west-2": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-us-west-2", - "objectKey": "39c10ea6874f35eed43cf997c541e6b3d9cc226c39ed6a0853f5583987455851.json", + "objectKey": "3ad82f621f535ba32c03341578f617dfd8f39e99b551e31245a1aa075c64ace7.json", "region": "us-west-2", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-us-west-2" } diff --git a/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.template.json b/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.template.json index 40d4401a..42739ac6 100644 --- a/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.template.json +++ b/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.template.json @@ -50,7 +50,7 @@ "RoleName": "AmazonBedrockExecutionRoleForAgents_awscdkbedrtTestAgent6A742A85" } }, - "TestAgentAgentFMPolicy7D053074": { + "TestAgentRoleDefaultPolicy0A38CDBA": { "Type": "AWS::IAM::Policy", "Properties": { "PolicyDocument": { @@ -58,6 +58,33 @@ { "Action": "bedrock:InvokeModel", "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":bedrock:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":foundation-model/anthropic.claude-3-sonnet-20240229-v1:0" + ] + ] + } + }, + { + "Action": [ + "bedrock:GetInferenceProfile", + "bedrock:ListInferenceProfiles" + ], + "Effect": "Allow", "Resource": { "Fn::Join": [ "", @@ -82,7 +109,7 @@ ], "Version": "2012-10-17" }, - "PolicyName": "TestAgentAgentFMPolicy7D053074", + "PolicyName": "TestAgentRoleDefaultPolicy0A38CDBA", "Roles": [ { "Ref": "TestAgentRole522C6259" @@ -129,7 +156,7 @@ ] ] }, - "Instruction": "You are a test resource that needs to be very gentle and useful to the user" + "Instruction": "You are a test bot that needs to be very gentle and useful to the user" } } }, diff --git a/test/integ/inference-profiles.integ.ts b/test/integ/inference-profiles.integ.ts index e6532e69..78fc14bb 100644 --- a/test/integ/inference-profiles.integ.ts +++ b/test/integ/inference-profiles.integ.ts @@ -14,6 +14,7 @@ import * as integ from "@aws-cdk/integ-tests-alpha"; import * as cdk from "aws-cdk-lib"; import { Agent, + ApplicationInferenceProfile, BedrockFoundationModel, CrossRegionInferenceProfile, CrossRegionInferenceProfileRegion, @@ -36,6 +37,22 @@ new Agent(stack, "TestAgent", { description: "test-description", }); +const myProjectApi = new ApplicationInferenceProfile(stack, "TestAppProfile", { + inferenceProfileName: "my-app-inf-profile", + tags: [{ key: "projectId", value: "supplyUSXRC28" }], + modelSource: CrossRegionInferenceProfile.fromConfig({ + geoRegion: CrossRegionInferenceProfileRegion.US, + model: BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0, + }), +}); + +// new Agent(stack, "TestAgent-2", { +// instruction: "You are a test bot that needs to be very gentle and useful to the user", +// model: myProjectApi, +// name: "test-agent-2", +// description: "test-description", +// }); + new integ.IntegTest(app, "ServiceTest", { testCases: [stack], cdkCommandOptions: { From e6a3c5aa116719e2ccbcc05bfb34ebbb6b53e71f Mon Sep 17 00:00:00 2001 From: Rafael Mosca Date: Fri, 15 Nov 2024 20:25:58 +0100 Subject: [PATCH 15/22] fix(bedrock): add test case 2 --- ...-bedrock-guardrails-integ-test.assets.json | 4 +-- ...edrock-guardrails-integ-test.template.json | 36 ++++++++++++++++++- test/integ/inference-profiles.integ.ts | 6 ++-- 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.assets.json b/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.assets.json index 6760607a..68b8fe8d 100644 --- a/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.assets.json +++ b/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.assets.json @@ -1,7 +1,7 @@ { "version": "38.0.1", "files": { - "3ad82f621f535ba32c03341578f617dfd8f39e99b551e31245a1aa075c64ace7": { + "03aa0c514f7316feaae4c91b323088e017e0ab4ffca7cce7f8b85bae49db40a0": { "source": { "path": "aws-cdk-bedrock-guardrails-integ-test.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-us-west-2": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-us-west-2", - "objectKey": "3ad82f621f535ba32c03341578f617dfd8f39e99b551e31245a1aa075c64ace7.json", + "objectKey": "03aa0c514f7316feaae4c91b323088e017e0ab4ffca7cce7f8b85bae49db40a0.json", "region": "us-west-2", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-us-west-2" } diff --git a/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.template.json b/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.template.json index 42739ac6..dec4951b 100644 --- a/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.template.json +++ b/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.template.json @@ -82,7 +82,7 @@ { "Action": [ "bedrock:GetInferenceProfile", - "bedrock:ListInferenceProfiles" + "bedrock:InvokeModel" ], "Effect": "Allow", "Resource": { @@ -158,6 +158,40 @@ }, "Instruction": "You are a test bot that needs to be very gentle and useful to the user" } + }, + "TestAppProfile97C615D8": { + "Type": "AWS::Bedrock::ApplicationInferenceProfile", + "Properties": { + "InferenceProfileName": "my-app-inf-profile", + "ModelSource": { + "CopyFrom": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":bedrock:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":inference-profile/us.anthropic.claude-3-sonnet-20240229-v1:0" + ] + ] + } + }, + "Tags": [ + { + "Key": "projectId", + "Value": "supplyUSXRC28" + } + ] + } } }, "Parameters": { diff --git a/test/integ/inference-profiles.integ.ts b/test/integ/inference-profiles.integ.ts index 78fc14bb..80b6b9e4 100644 --- a/test/integ/inference-profiles.integ.ts +++ b/test/integ/inference-profiles.integ.ts @@ -46,10 +46,10 @@ const myProjectApi = new ApplicationInferenceProfile(stack, "TestAppProfile", { }), }); -// new Agent(stack, "TestAgent-2", { -// instruction: "You are a test bot that needs to be very gentle and useful to the user", +// new Agent(stack, "TestAgent-23", { +// instruction: "You are a new test bot that needs to be very gentle and useful to the user", // model: myProjectApi, -// name: "test-agent-2", +// name: "test-agent-23", // description: "test-description", // }); From 43e780c384edf4ce26f3832000de6b95e13917ca Mon Sep 17 00:00:00 2001 From: krokoko Date: Mon, 18 Nov 2024 13:57:54 -0600 Subject: [PATCH 16/22] chore(doc): add missing auto generated doc --- apidocs/namespaces/bedrock/README.md | 9 +- apidocs/namespaces/bedrock/classes/Agent.md | 8 + .../classes/ApplicationInferenceProfile.md | 115 +++++++++++---- .../bedrock/classes/BedrockFoundationModel.md | 88 +++++++++++ .../classes/CrossRegionInferenceProfile.md | 138 ++++++++++++++++++ ...ProfileBase.md => InferenceProfileBase.md} | 70 ++++++--- .../CrossRegionInferenceProfileRegion.md | 31 ++++ .../enumerations/InferenceProfileType.md | 27 ++++ .../bedrock/interfaces/AgentProps.md | 16 +- .../ApplicationInferenceProfileProps.md | 2 +- .../interfaces/BedrockFoundationModelProps.md | 14 ++ .../interfaces/CommonPromptVariantProps.md | 2 +- .../CrossRegionInferenceProfileProps.md | 32 ++++ .../FoundationModelParsingStategyProps.md | 2 +- .../IApplicationInferenceProfile.md | 107 -------------- .../bedrock/interfaces/IInferenceProfile.md | 49 +++++++ .../bedrock/interfaces/IInvokable.md | 35 +++++ .../interfaces/TextPromptVariantProps.md | 2 +- 18 files changed, 573 insertions(+), 174 deletions(-) create mode 100644 apidocs/namespaces/bedrock/classes/CrossRegionInferenceProfile.md rename apidocs/namespaces/bedrock/classes/{ApplicationInferenceProfileBase.md => InferenceProfileBase.md} (81%) create mode 100644 apidocs/namespaces/bedrock/enumerations/CrossRegionInferenceProfileRegion.md create mode 100644 apidocs/namespaces/bedrock/enumerations/InferenceProfileType.md create mode 100644 apidocs/namespaces/bedrock/interfaces/CrossRegionInferenceProfileProps.md delete mode 100644 apidocs/namespaces/bedrock/interfaces/IApplicationInferenceProfile.md create mode 100644 apidocs/namespaces/bedrock/interfaces/IInferenceProfile.md create mode 100644 apidocs/namespaces/bedrock/interfaces/IInvokable.md diff --git a/apidocs/namespaces/bedrock/README.md b/apidocs/namespaces/bedrock/README.md index c00bc4ea..15d762e8 100644 --- a/apidocs/namespaces/bedrock/README.md +++ b/apidocs/namespaces/bedrock/README.md @@ -20,9 +20,11 @@ - [ContentFilterType](enumerations/ContentFilterType.md) - [ContextualGroundingFilterType](enumerations/ContextualGroundingFilterType.md) - [CrawlingScope](enumerations/CrawlingScope.md) +- [CrossRegionInferenceProfileRegion](enumerations/CrossRegionInferenceProfileRegion.md) - [DataDeletionPolicy](enumerations/DataDeletionPolicy.md) - [DataSourceType](enumerations/DataSourceType.md) - [GuardrailAction](enumerations/GuardrailAction.md) +- [InferenceProfileType](enumerations/InferenceProfileType.md) - [ManagedWordFilterType](enumerations/ManagedWordFilterType.md) - [ParserMode](enumerations/ParserMode.md) - [PromptCreationMode](enumerations/PromptCreationMode.md) @@ -42,16 +44,17 @@ - [AgentAlias](classes/AgentAlias.md) - [ApiSchema](classes/ApiSchema.md) - [ApplicationInferenceProfile](classes/ApplicationInferenceProfile.md) -- [ApplicationInferenceProfileBase](classes/ApplicationInferenceProfileBase.md) - [BedrockFoundationModel](classes/BedrockFoundationModel.md) - [ChunkingStrategy](classes/ChunkingStrategy.md) - [ConfluenceDataSource](classes/ConfluenceDataSource.md) +- [CrossRegionInferenceProfile](classes/CrossRegionInferenceProfile.md) - [CustomTransformation](classes/CustomTransformation.md) - [DataSource](classes/DataSource.md) - [DataSourceBase](classes/DataSourceBase.md) - [DataSourceNew](classes/DataSourceNew.md) - [Guardrail](classes/Guardrail.md) - [GuardrailBase](classes/GuardrailBase.md) +- [InferenceProfileBase](classes/InferenceProfileBase.md) - [InlineApiSchema](classes/InlineApiSchema.md) - [KnowledgeBase](classes/KnowledgeBase.md) - [ParsingStategy](classes/ParsingStategy.md) @@ -84,6 +87,7 @@ - [ContentFilter](interfaces/ContentFilter.md) - [ContextualGroundingFilter](interfaces/ContextualGroundingFilter.md) - [CrawlingFilters](interfaces/CrawlingFilters.md) +- [CrossRegionInferenceProfileProps](interfaces/CrossRegionInferenceProfileProps.md) - [CustomTopicProps](interfaces/CustomTopicProps.md) - [DataSourceAssociationProps](interfaces/DataSourceAssociationProps.md) - [FoundationModelParsingStategyProps](interfaces/FoundationModelParsingStategyProps.md) @@ -92,9 +96,10 @@ - [GuardrailProps](interfaces/GuardrailProps.md) - [HierarchicalChunkingProps](interfaces/HierarchicalChunkingProps.md) - [IAgentAlias](interfaces/IAgentAlias.md) -- [IApplicationInferenceProfile](interfaces/IApplicationInferenceProfile.md) - [IDataSource](interfaces/IDataSource.md) - [IGuardrail](interfaces/IGuardrail.md) +- [IInferenceProfile](interfaces/IInferenceProfile.md) +- [IInvokable](interfaces/IInvokable.md) - [IKnowledgeBase](interfaces/IKnowledgeBase.md) - [InferenceConfiguration](interfaces/InferenceConfiguration.md) - [IPrompt](interfaces/IPrompt.md) diff --git a/apidocs/namespaces/bedrock/classes/Agent.md b/apidocs/namespaces/bedrock/classes/Agent.md index 06d7c899..72131a73 100644 --- a/apidocs/namespaces/bedrock/classes/Agent.md +++ b/apidocs/namespaces/bedrock/classes/Agent.md @@ -106,6 +106,14 @@ A list of KnowledgeBases associated with the agent. *** +### model + +> `readonly` **model**: [`IInvokable`](../interfaces/IInvokable.md) + +The model used by the agent. + +*** + ### name > `readonly` **name**: `string` diff --git a/apidocs/namespaces/bedrock/classes/ApplicationInferenceProfile.md b/apidocs/namespaces/bedrock/classes/ApplicationInferenceProfile.md index 2dd14d20..674a034b 100644 --- a/apidocs/namespaces/bedrock/classes/ApplicationInferenceProfile.md +++ b/apidocs/namespaces/bedrock/classes/ApplicationInferenceProfile.md @@ -20,7 +20,11 @@ https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-create.h ## Extends -- [`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md) +- [`InferenceProfileBase`](InferenceProfileBase.md) + +## Implements + +- [`IInvokable`](../interfaces/IInvokable.md) ## Constructors @@ -42,7 +46,7 @@ https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-create.h #### Overrides -[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md).[`constructor`](ApplicationInferenceProfileBase.md#constructors) +[`InferenceProfileBase`](InferenceProfileBase.md).[`constructor`](InferenceProfileBase.md#constructors) ## Properties @@ -68,7 +72,7 @@ that might be different than the stack they were imported into. #### Inherited from -[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md).[`env`](ApplicationInferenceProfileBase.md#env) +[`InferenceProfileBase`](InferenceProfileBase.md).[`env`](InferenceProfileBase.md#env) *** @@ -80,7 +84,7 @@ The ARN of the application inference profile. #### Overrides -[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md).[`inferenceProfileArn`](ApplicationInferenceProfileBase.md#inferenceprofilearn) +[`InferenceProfileBase`](InferenceProfileBase.md).[`inferenceProfileArn`](InferenceProfileBase.md#inferenceprofilearn) *** @@ -92,19 +96,15 @@ The unique identifier of the inference profile. #### Overrides -[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md).[`inferenceProfileId`](ApplicationInferenceProfileBase.md#inferenceprofileid) +[`InferenceProfileBase`](InferenceProfileBase.md).[`inferenceProfileId`](InferenceProfileBase.md#inferenceprofileid) *** -### inferenceProfileIdentifier - -> `readonly` **inferenceProfileIdentifier**: `string` +### inferenceProfileModel -The ID or Amazon Resource Name (ARN) of the inference profile. +> `readonly` **inferenceProfileModel**: [`IInvokable`](../interfaces/IInvokable.md) -#### Overrides - -[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md).[`inferenceProfileIdentifier`](ApplicationInferenceProfileBase.md#inferenceprofileidentifier) +The unique identifier of the inference profile. *** @@ -116,6 +116,18 @@ The name of the application inference profile. *** +### invokableArn + +> `readonly` **invokableArn**: `string` + +This equals to the inferenceProfileArn property, useful just to implement IInvokable interface. + +#### Implementation of + +[`IInvokable`](../interfaces/IInvokable.md).[`invokableArn`](../interfaces/IInvokable.md#invokablearn) + +*** + ### node > `readonly` **node**: `Node` @@ -124,7 +136,7 @@ The tree node. #### Inherited from -[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md).[`node`](ApplicationInferenceProfileBase.md#node) +[`InferenceProfileBase`](InferenceProfileBase.md).[`node`](InferenceProfileBase.md#node) *** @@ -143,7 +155,7 @@ This value will resolve to one of the following: #### Inherited from -[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md).[`physicalName`](ApplicationInferenceProfileBase.md#physicalname) +[`InferenceProfileBase`](InferenceProfileBase.md).[`physicalName`](InferenceProfileBase.md#physicalname) *** @@ -155,7 +167,7 @@ The stack in which this resource is defined. #### Inherited from -[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md).[`stack`](ApplicationInferenceProfileBase.md#stack) +[`InferenceProfileBase`](InferenceProfileBase.md).[`stack`](InferenceProfileBase.md#stack) *** @@ -169,7 +181,7 @@ The status of the inference profile. ACTIVE means that the inference profile is ### type -> `readonly` **type**: `string` +> `readonly` **type**: [`InferenceProfileType`](../enumerations/InferenceProfileType.md) The type of the inference profile. The following types are possible: SYSTEM_DEFINED – The inference profile is defined by Amazon Bedrock. @@ -178,6 +190,10 @@ APPLICATION – The inference profile was created by a user. This type of inference profile can track metrics and costs when invoking the model in it. The inference profile may route requests to one or multiple regions. +#### Overrides + +[`InferenceProfileBase`](InferenceProfileBase.md).[`type`](InferenceProfileBase.md#type) + *** ### updatedAt @@ -205,7 +221,7 @@ through its absolute name/arn. #### Inherited from -[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md).[`_enableCrossEnvironment`](ApplicationInferenceProfileBase.md#_enablecrossenvironment) +[`InferenceProfileBase`](InferenceProfileBase.md).[`_enableCrossEnvironment`](InferenceProfileBase.md#_enablecrossenvironment) *** @@ -233,7 +249,7 @@ account for data recovery and cleanup later (`RemovalPolicy.RETAIN`). #### Inherited from -[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md).[`applyRemovalPolicy`](ApplicationInferenceProfileBase.md#applyremovalpolicy) +[`InferenceProfileBase`](InferenceProfileBase.md).[`applyRemovalPolicy`](InferenceProfileBase.md#applyremovalpolicy) *** @@ -247,7 +263,7 @@ account for data recovery and cleanup later (`RemovalPolicy.RETAIN`). #### Inherited from -[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md).[`generatePhysicalName`](ApplicationInferenceProfileBase.md#generatephysicalname) +[`InferenceProfileBase`](InferenceProfileBase.md).[`generatePhysicalName`](InferenceProfileBase.md#generatephysicalname) *** @@ -283,7 +299,7 @@ cross-environment references to work. #### Inherited from -[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md).[`getResourceArnAttribute`](ApplicationInferenceProfileBase.md#getresourcearnattribute) +[`InferenceProfileBase`](InferenceProfileBase.md).[`getResourceArnAttribute`](InferenceProfileBase.md#getresourcearnattribute) *** @@ -311,7 +327,48 @@ Commonly this is the resource's `ref`. #### Inherited from -[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md).[`getResourceNameAttribute`](ApplicationInferenceProfileBase.md#getresourcenameattribute) +[`InferenceProfileBase`](InferenceProfileBase.md).[`getResourceNameAttribute`](InferenceProfileBase.md#getresourcenameattribute) + +*** + +### grantInvoke() + +> **grantInvoke**(`grantee`): `Grant` + +Gives the appropriate policies to invoke and use the Foundation Model. + +#### Parameters + +• **grantee**: `IGrantable` + +#### Returns + +`Grant` + +#### Implementation of + +[`IInvokable`](../interfaces/IInvokable.md).[`grantInvoke`](../interfaces/IInvokable.md#grantinvoke) + +*** + +### grantProfileUsage() + +> **grantProfileUsage**(`grantee`): `Grant` + +Grants appropriate permissions to use the cross-region inference profile. +Does not grant permissions to use the model in the profile. + +#### Parameters + +• **grantee**: `IGrantable` + +#### Returns + +`Grant` + +#### Overrides + +[`InferenceProfileBase`](InferenceProfileBase.md).[`grantProfileUsage`](InferenceProfileBase.md#grantprofileusage) *** @@ -327,13 +384,13 @@ Returns a string representation of this construct. #### Inherited from -[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md).[`toString`](ApplicationInferenceProfileBase.md#tostring) +[`InferenceProfileBase`](InferenceProfileBase.md).[`toString`](InferenceProfileBase.md#tostring) *** ### fromApplicationInferenceProfileAttributes() -> `static` **fromApplicationInferenceProfileAttributes**(`scope`, `id`, `attrs`): [`IApplicationInferenceProfile`](../interfaces/IApplicationInferenceProfile.md) +> `static` **fromApplicationInferenceProfileAttributes**(`scope`, `id`, `attrs`): [`IInferenceProfile`](../interfaces/IInferenceProfile.md) Import a ApplicationInferenceProfile given its attributes @@ -347,13 +404,13 @@ Import a ApplicationInferenceProfile given its attributes #### Returns -[`IApplicationInferenceProfile`](../interfaces/IApplicationInferenceProfile.md) +[`IInferenceProfile`](../interfaces/IInferenceProfile.md) *** ### fromCfnApplicationInferenceProfile() -> `static` **fromCfnApplicationInferenceProfile**(`CfnApplicationInferenceProfile`): [`IApplicationInferenceProfile`](../interfaces/IApplicationInferenceProfile.md) +> `static` **fromCfnApplicationInferenceProfile**(`CfnApplicationInferenceProfile`): [`IInferenceProfile`](../interfaces/IInferenceProfile.md) Import a low-level L1 Cfn ApplicationInferenceProfile @@ -363,7 +420,7 @@ Import a low-level L1 Cfn ApplicationInferenceProfile #### Returns -[`IApplicationInferenceProfile`](../interfaces/IApplicationInferenceProfile.md) +[`IInferenceProfile`](../interfaces/IInferenceProfile.md) *** @@ -401,7 +458,7 @@ true if `x` is an object created from a class which extends `Construct`. #### Inherited from -[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md).[`isConstruct`](ApplicationInferenceProfileBase.md#isconstruct) +[`InferenceProfileBase`](InferenceProfileBase.md).[`isConstruct`](InferenceProfileBase.md#isconstruct) *** @@ -421,7 +478,7 @@ Returns true if the construct was created by CDK, and false otherwise #### Inherited from -[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md).[`isOwnedResource`](ApplicationInferenceProfileBase.md#isownedresource) +[`InferenceProfileBase`](InferenceProfileBase.md).[`isOwnedResource`](InferenceProfileBase.md#isownedresource) *** @@ -441,4 +498,4 @@ Check whether the given construct is a Resource #### Inherited from -[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md).[`isResource`](ApplicationInferenceProfileBase.md#isresource) +[`InferenceProfileBase`](InferenceProfileBase.md).[`isResource`](InferenceProfileBase.md#isresource) diff --git a/apidocs/namespaces/bedrock/classes/BedrockFoundationModel.md b/apidocs/namespaces/bedrock/classes/BedrockFoundationModel.md index e6349025..80579bff 100644 --- a/apidocs/namespaces/bedrock/classes/BedrockFoundationModel.md +++ b/apidocs/namespaces/bedrock/classes/BedrockFoundationModel.md @@ -11,6 +11,10 @@ Bedrock models. If you need to use a model name that doesn't exist as a static member, you can instantiate a `BedrockFoundationModel` object, e.g: `new BedrockFoundationModel('my-model')`. +## Implements + +- [`IInvokable`](../interfaces/IInvokable.md) + ## Constructors ### new BedrockFoundationModel() @@ -29,10 +33,32 @@ can instantiate a `BedrockFoundationModel` object, e.g: `new BedrockFoundationMo ## Properties +### invokableArn + +> `readonly` **invokableArn**: `string` + +The ARN of the Bedrock invokable abstraction. + +#### Implementation of + +[`IInvokable`](../interfaces/IInvokable.md).[`invokableArn`](../interfaces/IInvokable.md#invokablearn) + +*** + +### modelArn + +> `readonly` **modelArn**: `string` + +*** + ### modelId > `readonly` **modelId**: `string` +************************************************************************* + Constructor +************************************************************************* + *** ### supportsAgents @@ -41,6 +67,12 @@ can instantiate a `BedrockFoundationModel` object, e.g: `new BedrockFoundationMo *** +### supportsCrossRegion + +> `readonly` **supportsCrossRegion**: `boolean` + +*** + ### supportsKnowledgeBase > `readonly` **supportsKnowledgeBase**: `boolean` @@ -63,6 +95,10 @@ can instantiate a `BedrockFoundationModel` object, e.g: `new BedrockFoundationMo > `readonly` `static` **AMAZON\_TITAN\_TEXT\_EXPRESS\_V1**: [`BedrockFoundationModel`](BedrockFoundationModel.md) +************************************************************************* + AMAZON +************************************************************************* + *** ### ANTHROPIC\_CLAUDE\_3\_5\_HAIKU\_V1\_0 @@ -81,6 +117,10 @@ can instantiate a `BedrockFoundationModel` object, e.g: `new BedrockFoundationMo > `readonly` `static` **ANTHROPIC\_CLAUDE\_3\_5\_SONNET\_V2\_0**: [`BedrockFoundationModel`](BedrockFoundationModel.md) +************************************************************************* + ANTHROPIC +************************************************************************* + *** ### ANTHROPIC\_CLAUDE\_HAIKU\_V1\_0 @@ -123,6 +163,10 @@ can instantiate a `BedrockFoundationModel` object, e.g: `new BedrockFoundationMo > `readonly` `static` **COHERE\_EMBED\_ENGLISH\_V3**: [`BedrockFoundationModel`](BedrockFoundationModel.md) +************************************************************************* + COHERE +************************************************************************* + *** ### COHERE\_EMBED\_MULTILINGUAL\_V3 @@ -131,6 +175,28 @@ can instantiate a `BedrockFoundationModel` object, e.g: `new BedrockFoundationMo *** +### META\_LLAMA\_3\_2\_11B\_INSTRUCT\_V1 + +> `readonly` `static` **META\_LLAMA\_3\_2\_11B\_INSTRUCT\_V1**: [`BedrockFoundationModel`](BedrockFoundationModel.md) + +************************************************************************* + META +************************************************************************* + +*** + +### META\_LLAMA\_3\_2\_1B\_INSTRUCT\_V1 + +> `readonly` `static` **META\_LLAMA\_3\_2\_1B\_INSTRUCT\_V1**: [`BedrockFoundationModel`](BedrockFoundationModel.md) + +*** + +### META\_LLAMA\_3\_2\_3B\_INSTRUCT\_V1 + +> `readonly` `static` **META\_LLAMA\_3\_2\_3B\_INSTRUCT\_V1**: [`BedrockFoundationModel`](BedrockFoundationModel.md) + +*** + ### TITAN\_EMBED\_TEXT\_V1 > `readonly` `static` **TITAN\_EMBED\_TEXT\_V1**: [`BedrockFoundationModel`](BedrockFoundationModel.md) @@ -186,10 +252,32 @@ Returns the ARN of the foundation model in the following format: *** +### grantInvoke() + +> **grantInvoke**(`grantee`): `Grant` + +Gives the appropriate policies to invoke and use the Foundation Model. + +#### Parameters + +• **grantee**: `IGrantable` + +#### Returns + +`Grant` + +#### Implementation of + +[`IInvokable`](../interfaces/IInvokable.md).[`grantInvoke`](../interfaces/IInvokable.md#grantinvoke) + +*** + ### toString() > **toString**(): `string` +Returns a string representation of an object. + #### Returns `string` diff --git a/apidocs/namespaces/bedrock/classes/CrossRegionInferenceProfile.md b/apidocs/namespaces/bedrock/classes/CrossRegionInferenceProfile.md new file mode 100644 index 00000000..60c6f76d --- /dev/null +++ b/apidocs/namespaces/bedrock/classes/CrossRegionInferenceProfile.md @@ -0,0 +1,138 @@ +[**@cdklabs/generative-ai-cdk-constructs**](../../../README.md) • **Docs** + +*** + +[@cdklabs/generative-ai-cdk-constructs](../../../README.md) / [bedrock](../README.md) / CrossRegionInferenceProfile + +# Class: CrossRegionInferenceProfile + +Cross-region inference enables you to seamlessly manage unplanned traffic +bursts by utilizing compute across different AWS Regions. With cross-region +inference, you can distribute traffic across multiple AWS Regions, enabling +higher throughput and enhanced resilience during periods of peak demands. + +## See + +https://docs.aws.amazon.com/bedrock/latest/userguide/cross-region-inference.html + +## Implements + +- [`IInvokable`](../interfaces/IInvokable.md) +- [`IInferenceProfile`](../interfaces/IInferenceProfile.md) + +## Properties + +### inferenceProfileArn + +> `readonly` **inferenceProfileArn**: `string` + +#### Example + +```ts +'arn:aws:bedrock:us-east-1:123456789012:inference-profile/us.anthropic.claude-3-5-sonnet-20240620-v1:0' +``` + +#### Implementation of + +[`IInferenceProfile`](../interfaces/IInferenceProfile.md).[`inferenceProfileArn`](../interfaces/IInferenceProfile.md#inferenceprofilearn) + +*** + +### inferenceProfileId + +> `readonly` **inferenceProfileId**: `string` + +#### Example + +```ts +'us.anthropic.claude-3-5-sonnet-20240620-v1:0' +``` + +#### Implementation of + +[`IInferenceProfile`](../interfaces/IInferenceProfile.md).[`inferenceProfileId`](../interfaces/IInferenceProfile.md#inferenceprofileid) + +*** + +### inferenceProfileModel + +> `readonly` **inferenceProfileModel**: [`BedrockFoundationModel`](BedrockFoundationModel.md) + +*** + +### invokableArn + +> `readonly` **invokableArn**: `string` + +This equals to the inferenceProfileArn property, useful just to implement IInvokable interface + +#### Implementation of + +[`IInvokable`](../interfaces/IInvokable.md).[`invokableArn`](../interfaces/IInvokable.md#invokablearn) + +*** + +### type + +> `readonly` **type**: [`InferenceProfileType`](../enumerations/InferenceProfileType.md) + +The type of inference profile. + +#### Implementation of + +[`IInferenceProfile`](../interfaces/IInferenceProfile.md).[`type`](../interfaces/IInferenceProfile.md#type) + +## Methods + +### grantInvoke() + +> **grantInvoke**(`grantee`): `Grant` + +Gives the appropriate policies to invoke and use the Foundation Model. + +#### Parameters + +• **grantee**: `IGrantable` + +#### Returns + +`Grant` + +#### Implementation of + +[`IInvokable`](../interfaces/IInvokable.md).[`grantInvoke`](../interfaces/IInvokable.md#grantinvoke) + +*** + +### grantProfileUsage() + +> **grantProfileUsage**(`grantee`): `Grant` + +Grants appropriate permissions to use the cross-region inference profile. +Does not grant permissions to use the model in the profile. + +#### Parameters + +• **grantee**: `IGrantable` + +#### Returns + +`Grant` + +#### Implementation of + +[`IInferenceProfile`](../interfaces/IInferenceProfile.md).[`grantProfileUsage`](../interfaces/IInferenceProfile.md#grantprofileusage) + +*** + +### fromConfig() + +> `static` **fromConfig**(`config`): [`CrossRegionInferenceProfile`](CrossRegionInferenceProfile.md) + +#### Parameters + +• **config**: [`CrossRegionInferenceProfileProps`](../interfaces/CrossRegionInferenceProfileProps.md) + +#### Returns + +[`CrossRegionInferenceProfile`](CrossRegionInferenceProfile.md) diff --git a/apidocs/namespaces/bedrock/classes/ApplicationInferenceProfileBase.md b/apidocs/namespaces/bedrock/classes/InferenceProfileBase.md similarity index 81% rename from apidocs/namespaces/bedrock/classes/ApplicationInferenceProfileBase.md rename to apidocs/namespaces/bedrock/classes/InferenceProfileBase.md index 6aa7c3c2..d4076e27 100644 --- a/apidocs/namespaces/bedrock/classes/ApplicationInferenceProfileBase.md +++ b/apidocs/namespaces/bedrock/classes/InferenceProfileBase.md @@ -2,9 +2,9 @@ *** -[@cdklabs/generative-ai-cdk-constructs](../../../README.md) / [bedrock](../README.md) / ApplicationInferenceProfileBase +[@cdklabs/generative-ai-cdk-constructs](../../../README.md) / [bedrock](../README.md) / InferenceProfileBase -# Class: `abstract` ApplicationInferenceProfileBase +# Class: `abstract` InferenceProfileBase Abstract base class for a ApplicationInferenceProfile. Contains methods and attributes valid for ApplicationInferenceProfiles either created with CDK or imported. @@ -19,13 +19,14 @@ Contains methods and attributes valid for ApplicationInferenceProfiles either cr ## Implements -- [`IApplicationInferenceProfile`](../interfaces/IApplicationInferenceProfile.md) +- [`IInferenceProfile`](../interfaces/IInferenceProfile.md) +- `IResource` ## Constructors -### new ApplicationInferenceProfileBase() +### new InferenceProfileBase() -> **new ApplicationInferenceProfileBase**(`scope`, `id`, `props`?): [`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md) +> **new InferenceProfileBase**(`scope`, `id`, `props`?): [`InferenceProfileBase`](InferenceProfileBase.md) #### Parameters @@ -37,7 +38,7 @@ Contains methods and attributes valid for ApplicationInferenceProfiles either cr #### Returns -[`ApplicationInferenceProfileBase`](ApplicationInferenceProfileBase.md) +[`InferenceProfileBase`](InferenceProfileBase.md) #### Inherited from @@ -59,7 +60,7 @@ that might be different than the stack they were imported into. #### Implementation of -[`IApplicationInferenceProfile`](../interfaces/IApplicationInferenceProfile.md).[`env`](../interfaces/IApplicationInferenceProfile.md#env) +`IResource.env` #### Inherited from @@ -75,7 +76,7 @@ The ARN of the application inference profile. #### Implementation of -[`IApplicationInferenceProfile`](../interfaces/IApplicationInferenceProfile.md).[`inferenceProfileArn`](../interfaces/IApplicationInferenceProfile.md#inferenceprofilearn) +[`IInferenceProfile`](../interfaces/IInferenceProfile.md).[`inferenceProfileArn`](../interfaces/IInferenceProfile.md#inferenceprofilearn) *** @@ -87,19 +88,7 @@ The unique identifier of the inference profile. #### Implementation of -[`IApplicationInferenceProfile`](../interfaces/IApplicationInferenceProfile.md).[`inferenceProfileId`](../interfaces/IApplicationInferenceProfile.md#inferenceprofileid) - -*** - -### inferenceProfileIdentifier - -> `abstract` `readonly` **inferenceProfileIdentifier**: `string` - -The ID or Amazon Resource Name (ARN) of the inference profile. - -#### Implementation of - -[`IApplicationInferenceProfile`](../interfaces/IApplicationInferenceProfile.md).[`inferenceProfileIdentifier`](../interfaces/IApplicationInferenceProfile.md#inferenceprofileidentifier) +[`IInferenceProfile`](../interfaces/IInferenceProfile.md).[`inferenceProfileId`](../interfaces/IInferenceProfile.md#inferenceprofileid) *** @@ -111,7 +100,7 @@ The tree node. #### Implementation of -[`IApplicationInferenceProfile`](../interfaces/IApplicationInferenceProfile.md).[`node`](../interfaces/IApplicationInferenceProfile.md#node) +`IResource.node` #### Inherited from @@ -146,12 +135,24 @@ The stack in which this resource is defined. #### Implementation of -[`IApplicationInferenceProfile`](../interfaces/IApplicationInferenceProfile.md).[`stack`](../interfaces/IApplicationInferenceProfile.md#stack) +`IResource.stack` #### Inherited from `Resource.stack` +*** + +### type + +> `abstract` `readonly` **type**: [`InferenceProfileType`](../enumerations/InferenceProfileType.md) + +The ID or Amazon Resource Name (ARN) of the inference profile. + +#### Implementation of + +[`IInferenceProfile`](../interfaces/IInferenceProfile.md).[`type`](../interfaces/IInferenceProfile.md#type) + ## Methods ### \_enableCrossEnvironment() @@ -199,7 +200,7 @@ account for data recovery and cleanup later (`RemovalPolicy.RETAIN`). #### Implementation of -[`IApplicationInferenceProfile`](../interfaces/IApplicationInferenceProfile.md).[`applyRemovalPolicy`](../interfaces/IApplicationInferenceProfile.md#applyremovalpolicy) +`IResource.applyRemovalPolicy` #### Inherited from @@ -285,6 +286,27 @@ Commonly this is the resource's `ref`. *** +### grantProfileUsage() + +> **grantProfileUsage**(`grantee`): `Grant` + +Grants appropriate permissions to use the cross-region inference profile. +Does not grant permissions to use the model in the profile. + +#### Parameters + +• **grantee**: `IGrantable` + +#### Returns + +`Grant` + +#### Implementation of + +[`IInferenceProfile`](../interfaces/IInferenceProfile.md).[`grantProfileUsage`](../interfaces/IInferenceProfile.md#grantprofileusage) + +*** + ### toString() > **toString**(): `string` diff --git a/apidocs/namespaces/bedrock/enumerations/CrossRegionInferenceProfileRegion.md b/apidocs/namespaces/bedrock/enumerations/CrossRegionInferenceProfileRegion.md new file mode 100644 index 00000000..37cafeac --- /dev/null +++ b/apidocs/namespaces/bedrock/enumerations/CrossRegionInferenceProfileRegion.md @@ -0,0 +1,31 @@ +[**@cdklabs/generative-ai-cdk-constructs**](../../../README.md) • **Docs** + +*** + +[@cdklabs/generative-ai-cdk-constructs](../../../README.md) / [bedrock](../README.md) / CrossRegionInferenceProfileRegion + +# Enumeration: CrossRegionInferenceProfileRegion + +## Enumeration Members + +### APAC + +> **APAC**: `"apac"` + +This might include: ap-northeast-1, ap-northeast-2, ap-south-1, ap-southeast-1, and ap-southeast-2 + +*** + +### EU + +> **EU**: `"eu"` + +EU: Frankfurt (eu-central-1), Ireland (eu-west-1), Paris (eu-west-3) + +*** + +### US + +> **US**: `"us"` + +US: N. Virginia (us-east-1), Oregon (us-west-2) diff --git a/apidocs/namespaces/bedrock/enumerations/InferenceProfileType.md b/apidocs/namespaces/bedrock/enumerations/InferenceProfileType.md new file mode 100644 index 00000000..cabcc6e3 --- /dev/null +++ b/apidocs/namespaces/bedrock/enumerations/InferenceProfileType.md @@ -0,0 +1,27 @@ +[**@cdklabs/generative-ai-cdk-constructs**](../../../README.md) • **Docs** + +*** + +[@cdklabs/generative-ai-cdk-constructs](../../../README.md) / [bedrock](../README.md) / InferenceProfileType + +# Enumeration: InferenceProfileType + +These are the values used by the API when using aws bedrock get-inference-profile --inference-profile-identifier XXXXXXX + +## Enumeration Members + +### APPLICATION + +> **APPLICATION**: `"APPLICATION"` + +An inference profile that is user-created. These are profiles that help +you track costs or metrics. + +*** + +### SYSTEM\_DEFINED + +> **SYSTEM\_DEFINED**: `"SYSTEM_DEFINED"` + +An inference profile that is created by AWS. These are profiles such as cross-region +which help you distributed traffic across a geographic region. diff --git a/apidocs/namespaces/bedrock/interfaces/AgentProps.md b/apidocs/namespaces/bedrock/interfaces/AgentProps.md index ddb5b92f..b4dea498 100644 --- a/apidocs/namespaces/bedrock/interfaces/AgentProps.md +++ b/apidocs/namespaces/bedrock/interfaces/AgentProps.md @@ -91,14 +91,6 @@ allows the Bedrock service to assume the role. *** -### foundationModel - -> `readonly` **foundationModel**: [`BedrockFoundationModel`](../classes/BedrockFoundationModel.md) - -The Bedrock text foundation model for the agent to use. - -*** - ### guardrailConfiguration? > `readonly` `optional` **guardrailConfiguration**: [`GuardrailConfiguration`](GuardrailConfiguration.md) @@ -154,6 +146,14 @@ Knowledge Bases to make available to the agent. *** +### model + +> `readonly` **model**: [`IInvokable`](IInvokable.md) + +The Bedrock text foundation model for the agent to use. + +*** + ### name? > `readonly` `optional` **name**: `string` diff --git a/apidocs/namespaces/bedrock/interfaces/ApplicationInferenceProfileProps.md b/apidocs/namespaces/bedrock/interfaces/ApplicationInferenceProfileProps.md index 1c2fbd62..8f3af826 100644 --- a/apidocs/namespaces/bedrock/interfaces/ApplicationInferenceProfileProps.md +++ b/apidocs/namespaces/bedrock/interfaces/ApplicationInferenceProfileProps.md @@ -36,7 +36,7 @@ http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-bedro ### modelSource -> `readonly` **modelSource**: `string` +> `readonly` **modelSource**: [`IInvokable`](IInvokable.md) To create an application inference profile for one Region, specify a foundation model. Usage and costs for requests made to that Region with that model will be tracked. diff --git a/apidocs/namespaces/bedrock/interfaces/BedrockFoundationModelProps.md b/apidocs/namespaces/bedrock/interfaces/BedrockFoundationModelProps.md index d9e537fb..d53e5622 100644 --- a/apidocs/namespaces/bedrock/interfaces/BedrockFoundationModelProps.md +++ b/apidocs/namespaces/bedrock/interfaces/BedrockFoundationModelProps.md @@ -22,6 +22,20 @@ Bedrock Agents can use this model. *** +### supportsCrossRegion? + +> `readonly` `optional` **supportsCrossRegion**: `boolean` + +Can be used with a Cross-Region Inference Profile + +#### Default + +```ts +- false +``` + +*** + ### supportsKnowledgeBase? > `readonly` `optional` **supportsKnowledgeBase**: `boolean` diff --git a/apidocs/namespaces/bedrock/interfaces/CommonPromptVariantProps.md b/apidocs/namespaces/bedrock/interfaces/CommonPromptVariantProps.md index 0039566c..6ca83574 100644 --- a/apidocs/namespaces/bedrock/interfaces/CommonPromptVariantProps.md +++ b/apidocs/namespaces/bedrock/interfaces/CommonPromptVariantProps.md @@ -14,7 +14,7 @@ ### model -> `readonly` **model**: `IModel` +> `readonly` **model**: [`IInvokable`](IInvokable.md) The model which is used to run the prompt. The model could be a foundation model, a custom model, or a provisioned model. diff --git a/apidocs/namespaces/bedrock/interfaces/CrossRegionInferenceProfileProps.md b/apidocs/namespaces/bedrock/interfaces/CrossRegionInferenceProfileProps.md new file mode 100644 index 00000000..27bab6a1 --- /dev/null +++ b/apidocs/namespaces/bedrock/interfaces/CrossRegionInferenceProfileProps.md @@ -0,0 +1,32 @@ +[**@cdklabs/generative-ai-cdk-constructs**](../../../README.md) • **Docs** + +*** + +[@cdklabs/generative-ai-cdk-constructs](../../../README.md) / [bedrock](../README.md) / CrossRegionInferenceProfileProps + +# Interface: CrossRegionInferenceProfileProps + +*************************************************************************** + PROPS FOR NEW CONSTRUCT +*************************************************************************** + +## Properties + +### geoRegion + +> `readonly` **geoRegion**: [`CrossRegionInferenceProfileRegion`](../enumerations/CrossRegionInferenceProfileRegion.md) + +The geographic region where the traffic is going to be distributed. Routing +factors in user traffic, demand and utilization of resources. + +*** + +### model + +> `readonly` **model**: [`BedrockFoundationModel`](../classes/BedrockFoundationModel.md) + +A model supporting cross-region inference. + +#### See + +https://docs.aws.amazon.com/bedrock/latest/userguide/cross-region-inference-support.html diff --git a/apidocs/namespaces/bedrock/interfaces/FoundationModelParsingStategyProps.md b/apidocs/namespaces/bedrock/interfaces/FoundationModelParsingStategyProps.md index 1a57624c..c3d39f98 100644 --- a/apidocs/namespaces/bedrock/interfaces/FoundationModelParsingStategyProps.md +++ b/apidocs/namespaces/bedrock/interfaces/FoundationModelParsingStategyProps.md @@ -12,7 +12,7 @@ Properties for configuring a Foundation Model parsing strategy. ### parsingModel -> `readonly` **parsingModel**: `IModel` +> `readonly` **parsingModel**: [`IInvokable`](IInvokable.md) The Foundation Model to use for parsing non-textual information. Currently supported models are Claude 3 Sonnet and Claude 3 Haiku. diff --git a/apidocs/namespaces/bedrock/interfaces/IApplicationInferenceProfile.md b/apidocs/namespaces/bedrock/interfaces/IApplicationInferenceProfile.md deleted file mode 100644 index 45af9036..00000000 --- a/apidocs/namespaces/bedrock/interfaces/IApplicationInferenceProfile.md +++ /dev/null @@ -1,107 +0,0 @@ -[**@cdklabs/generative-ai-cdk-constructs**](../../../README.md) • **Docs** - -*** - -[@cdklabs/generative-ai-cdk-constructs](../../../README.md) / [bedrock](../README.md) / IApplicationInferenceProfile - -# Interface: IApplicationInferenceProfile - -Represents a ApplicationInferenceProfile, either created with CDK or imported. - -## Extends - -- `IResource` - -## Properties - -### env - -> `readonly` **env**: `ResourceEnvironment` - -The environment this resource belongs to. -For resources that are created and managed by the CDK -(generally, those created by creating new class instances like Role, Bucket, etc.), -this is always the same as the environment of the stack they belong to; -however, for imported resources -(those obtained from static methods like fromRoleArn, fromBucketName, etc.), -that might be different than the stack they were imported into. - -#### Inherited from - -`IResource.env` - -*** - -### inferenceProfileArn - -> `readonly` **inferenceProfileArn**: `string` - -The ARN of the application inference profile. - -*** - -### inferenceProfileId - -> `readonly` **inferenceProfileId**: `string` - -The unique identifier of the inference profile. - -*** - -### inferenceProfileIdentifier - -> `readonly` **inferenceProfileIdentifier**: `string` - -The ID or Amazon Resource Name (ARN) of the inference profile. - -*** - -### node - -> `readonly` **node**: `Node` - -The tree node. - -#### Inherited from - -`IResource.node` - -*** - -### stack - -> `readonly` **stack**: `Stack` - -The stack in which this resource is defined. - -#### Inherited from - -`IResource.stack` - -## Methods - -### applyRemovalPolicy() - -> **applyRemovalPolicy**(`policy`): `void` - -Apply the given removal policy to this resource - -The Removal Policy controls what happens to this resource when it stops -being managed by CloudFormation, either because you've removed it from the -CDK application or because you've made a change that requires the resource -to be replaced. - -The resource can be deleted (`RemovalPolicy.DESTROY`), or left in your AWS -account for data recovery and cleanup later (`RemovalPolicy.RETAIN`). - -#### Parameters - -• **policy**: `RemovalPolicy` - -#### Returns - -`void` - -#### Inherited from - -`IResource.applyRemovalPolicy` diff --git a/apidocs/namespaces/bedrock/interfaces/IInferenceProfile.md b/apidocs/namespaces/bedrock/interfaces/IInferenceProfile.md new file mode 100644 index 00000000..bf57e911 --- /dev/null +++ b/apidocs/namespaces/bedrock/interfaces/IInferenceProfile.md @@ -0,0 +1,49 @@ +[**@cdklabs/generative-ai-cdk-constructs**](../../../README.md) • **Docs** + +*** + +[@cdklabs/generative-ai-cdk-constructs](../../../README.md) / [bedrock](../README.md) / IInferenceProfile + +# Interface: IInferenceProfile + +Represents a ApplicationInferenceProfile, either created with CDK or imported. + +## Properties + +### inferenceProfileArn + +> `readonly` **inferenceProfileArn**: `string` + +The ARN of the application inference profile. + +*** + +### inferenceProfileId + +> `readonly` **inferenceProfileId**: `string` + +The unique identifier of the inference profile. + +*** + +### type + +> `readonly` **type**: [`InferenceProfileType`](../enumerations/InferenceProfileType.md) + +The type of inference profile. + +## Methods + +### grantProfileUsage() + +> **grantProfileUsage**(`grantee`): `Grant` + +Grants appropriate permissions to use the inference profile. + +#### Parameters + +• **grantee**: `IGrantable` + +#### Returns + +`Grant` diff --git a/apidocs/namespaces/bedrock/interfaces/IInvokable.md b/apidocs/namespaces/bedrock/interfaces/IInvokable.md new file mode 100644 index 00000000..392f43ca --- /dev/null +++ b/apidocs/namespaces/bedrock/interfaces/IInvokable.md @@ -0,0 +1,35 @@ +[**@cdklabs/generative-ai-cdk-constructs**](../../../README.md) • **Docs** + +*** + +[@cdklabs/generative-ai-cdk-constructs](../../../README.md) / [bedrock](../README.md) / IInvokable + +# Interface: IInvokable + +Represents an Amazon Bedrock abstraction on which you can +run the `Invoke` API. This can be a Foundational Model, +a Custom Model, or an Inference Profile. + +## Properties + +### invokableArn + +> `readonly` **invokableArn**: `string` + +The ARN of the Bedrock invokable abstraction. + +## Methods + +### grantInvoke() + +> **grantInvoke**(`grantee`): `Grant` + +Gives the appropriate policies to invoke and use the invokable abstraction. + +#### Parameters + +• **grantee**: `IGrantable` + +#### Returns + +`Grant` diff --git a/apidocs/namespaces/bedrock/interfaces/TextPromptVariantProps.md b/apidocs/namespaces/bedrock/interfaces/TextPromptVariantProps.md index b3b6f8e2..0a2d2f28 100644 --- a/apidocs/namespaces/bedrock/interfaces/TextPromptVariantProps.md +++ b/apidocs/namespaces/bedrock/interfaces/TextPromptVariantProps.md @@ -22,7 +22,7 @@ Inference configuration for the Text Prompt ### model -> `readonly` **model**: `IModel` +> `readonly` **model**: [`IInvokable`](IInvokable.md) The model which is used to run the prompt. The model could be a foundation model, a custom model, or a provisioned model. From f3a6927f9ed7d2861113540c9448a8038b487113 Mon Sep 17 00:00:00 2001 From: krokoko Date: Tue, 19 Nov 2024 16:05:06 -0600 Subject: [PATCH 17/22] chore(cris): add support in prompts and agents for cris --- apidocs/namespaces/bedrock/classes/Agent.md | 16 +- .../bedrock/classes/BedrockFoundationModel.md | 32 ++++ .../bedrock/interfaces/AgentProps.md | 16 +- src/cdk-lib/bedrock/agent.ts | 131 +++++++------- src/cdk-lib/bedrock/data-sources/parsing.ts | 12 +- src/cdk-lib/bedrock/index.ts | 44 ++--- .../application-inference-profile.ts | 46 +++-- .../bedrock/inference-profiles/common.ts | 10 +- .../cross-region-inference-profile.ts | 52 ++++-- src/cdk-lib/bedrock/models.ts | 77 +++++---- src/cdk-lib/bedrock/prompts/prompt.ts | 24 +-- .../data-sources/s3-data-source.test.ts | 136 +++++++-------- .../cdk-lib/bedrock/inference-profile.test.ts | 161 ++++++++---------- test/cdk-lib/bedrock/prompts.test.ts | 116 ++++++++++++- ...-bedrock-guardrails-integ-test.assets.json | 4 +- ...edrock-guardrails-integ-test.template.json | 22 ++- test/integ/inference-profiles.integ.ts | 35 ++-- 17 files changed, 550 insertions(+), 384 deletions(-) diff --git a/apidocs/namespaces/bedrock/classes/Agent.md b/apidocs/namespaces/bedrock/classes/Agent.md index 72131a73..c62d2c26 100644 --- a/apidocs/namespaces/bedrock/classes/Agent.md +++ b/apidocs/namespaces/bedrock/classes/Agent.md @@ -92,6 +92,14 @@ The name for the agent alias. *** +### foundationModel + +> `readonly` **foundationModel**: [`IInvokable`](../interfaces/IInvokable.md) + +The model used by the agent. + +*** + ### knowledgeBases > **knowledgeBases**: `AgentKnowledgeBaseProperty`[] = `[]` @@ -106,14 +114,6 @@ A list of KnowledgeBases associated with the agent. *** -### model - -> `readonly` **model**: [`IInvokable`](../interfaces/IInvokable.md) - -The model used by the agent. - -*** - ### name > `readonly` **name**: `string` diff --git a/apidocs/namespaces/bedrock/classes/BedrockFoundationModel.md b/apidocs/namespaces/bedrock/classes/BedrockFoundationModel.md index 80579bff..0637d10c 100644 --- a/apidocs/namespaces/bedrock/classes/BedrockFoundationModel.md +++ b/apidocs/namespaces/bedrock/classes/BedrockFoundationModel.md @@ -281,3 +281,35 @@ Returns a string representation of an object. #### Returns `string` + +*** + +### fromCdkFoundationModel() + +> `static` **fromCdkFoundationModel**(`modelId`, `props`): [`BedrockFoundationModel`](BedrockFoundationModel.md) + +#### Parameters + +• **modelId**: `FoundationModel` + +• **props**: [`BedrockFoundationModelProps`](../interfaces/BedrockFoundationModelProps.md) = `{}` + +#### Returns + +[`BedrockFoundationModel`](BedrockFoundationModel.md) + +*** + +### fromCdkFoundationModelId() + +> `static` **fromCdkFoundationModelId**(`modelId`, `props`): [`BedrockFoundationModel`](BedrockFoundationModel.md) + +#### Parameters + +• **modelId**: `FoundationModelIdentifier` + +• **props**: [`BedrockFoundationModelProps`](../interfaces/BedrockFoundationModelProps.md) = `{}` + +#### Returns + +[`BedrockFoundationModel`](BedrockFoundationModel.md) diff --git a/apidocs/namespaces/bedrock/interfaces/AgentProps.md b/apidocs/namespaces/bedrock/interfaces/AgentProps.md index b4dea498..3077c935 100644 --- a/apidocs/namespaces/bedrock/interfaces/AgentProps.md +++ b/apidocs/namespaces/bedrock/interfaces/AgentProps.md @@ -91,6 +91,14 @@ allows the Bedrock service to assume the role. *** +### foundationModel + +> `readonly` **foundationModel**: [`IInvokable`](IInvokable.md) + +The Bedrock text foundation model for the agent to use. + +*** + ### guardrailConfiguration? > `readonly` `optional` **guardrailConfiguration**: [`GuardrailConfiguration`](GuardrailConfiguration.md) @@ -146,14 +154,6 @@ Knowledge Bases to make available to the agent. *** -### model - -> `readonly` **model**: [`IInvokable`](IInvokable.md) - -The Bedrock text foundation model for the agent to use. - -*** - ### name? > `readonly` `optional` **name**: `string` diff --git a/src/cdk-lib/bedrock/agent.ts b/src/cdk-lib/bedrock/agent.ts index b4a73c8e..8036767f 100644 --- a/src/cdk-lib/bedrock/agent.ts +++ b/src/cdk-lib/bedrock/agent.ts @@ -11,27 +11,27 @@ * and limitations under the License. */ -import * as cdk from "aws-cdk-lib"; -import { aws_bedrock as bedrock } from "aws-cdk-lib"; -import * as iam from "aws-cdk-lib/aws-iam"; -import * as kms from "aws-cdk-lib/aws-kms"; -import { Construct } from "constructs"; - -import { AgentActionGroup } from "./agent-action-group"; -import { AgentAlias } from "./agent-alias"; -import { IGuardrail } from "./guardrails/guardrails"; -import { KnowledgeBase } from "./knowledge-base"; -import { IInvokable } from "./models"; -import { generatePhysicalNameV2 } from "../../common/helpers/utils"; +import * as cdk from 'aws-cdk-lib'; +import { aws_bedrock as bedrock } from 'aws-cdk-lib'; +import * as iam from 'aws-cdk-lib/aws-iam'; +import * as kms from 'aws-cdk-lib/aws-kms'; +import { Construct } from 'constructs'; + +import { AgentActionGroup } from './agent-action-group'; +import { AgentAlias } from './agent-alias'; +import { IGuardrail } from './guardrails/guardrails'; +import { KnowledgeBase } from './knowledge-base'; +import { IInvokable } from './models'; +import { generatePhysicalNameV2 } from '../../common/helpers/utils'; /** * The step in the agent sequence that this prompt configuration applies to. */ export enum PromptType { - PRE_PROCESSING = "PRE_PROCESSING", - ORCHESTRATION = "ORCHESTRATION", - POST_PROCESSING = "POST_PROCESSING", - KNOWLEDGE_BASE_RESPONSE_GENERATION = "KNOWLEDGE_BASE_RESPONSE_GENERATION", + PRE_PROCESSING = 'PRE_PROCESSING', + ORCHESTRATION = 'ORCHESTRATION', + POST_PROCESSING = 'POST_PROCESSING', + KNOWLEDGE_BASE_RESPONSE_GENERATION = 'KNOWLEDGE_BASE_RESPONSE_GENERATION', } /** @@ -42,8 +42,8 @@ export enum PromptType { * with the ARN of a Lambda function. */ export enum ParserMode { - DEFAULT = "DEFAULT", - OVERRIDDEN = "OVERRIDDEN", + DEFAULT = 'DEFAULT', + OVERRIDDEN = 'OVERRIDDEN', } /** @@ -53,8 +53,8 @@ export enum ParserMode { * uses a default prompt template. */ export enum PromptCreationMode { - DEFAULT = "DEFAULT", - OVERRIDDEN = "OVERRIDDEN", + DEFAULT = 'DEFAULT', + OVERRIDDEN = 'OVERRIDDEN', } /** @@ -68,8 +68,8 @@ export enum PromptCreationMode { * POST_PROCESSING – DISABLED */ export enum PromptState { - ENABLED = "ENABLED", - DISABLED = "DISABLED", + ENABLED = 'ENABLED', + DISABLED = 'DISABLED', } /** Details about the guardrail associated with the agent. */ @@ -212,7 +212,7 @@ export interface AgentProps { /** * The Bedrock text foundation model for the agent to use. */ - readonly model: IInvokable; + readonly foundationModel: IInvokable; /** * The name of the agent. * @@ -343,7 +343,7 @@ export class Agent extends Construct { /** * The model used by the agent. */ - public readonly model: IInvokable; + public readonly foundationModel: IInvokable; /** * The unique identifier of the agent. */ @@ -394,47 +394,45 @@ export class Agent extends Construct { super(scope, id); validatePromptOverrideConfiguration(props.promptOverrideConfiguration); - //validateModel(props.foundationModel); - - this.model = props.model; + this.foundationModel = props.foundationModel; this.name = - props.name ?? generatePhysicalNameV2(this, "bedrock-agent", { maxLength: 32, lower: true, separator: "-" }); + props.name ?? generatePhysicalNameV2(this, 'bedrock-agent', { maxLength: 32, lower: true, separator: '-' }); if (props.existingRole) { this.role = props.existingRole; } else { - this.role = new iam.Role(this, "Role", { - assumedBy: new iam.ServicePrincipal("bedrock.amazonaws.com"), - roleName: generatePhysicalNameV2(this, "AmazonBedrockExecutionRoleForAgents_", { maxLength: 64, lower: false }), + this.role = new iam.Role(this, 'Role', { + assumedBy: new iam.ServicePrincipal('bedrock.amazonaws.com'), + roleName: generatePhysicalNameV2(this, 'AmazonBedrockExecutionRoleForAgents_', { maxLength: 64, lower: false }), }); this.role.assumeRolePolicy!.addStatements( new iam.PolicyStatement({ - actions: ["sts:AssumeRole"], - principals: [new iam.ServicePrincipal("bedrock.amazonaws.com")], + actions: ['sts:AssumeRole'], + principals: [new iam.ServicePrincipal('bedrock.amazonaws.com')], conditions: { StringEquals: { - "aws:SourceAccount": cdk.Stack.of(this).account, + 'aws:SourceAccount': cdk.Stack.of(this).account, }, ArnLike: { - "aws:SourceArn": cdk.Stack.of(this).formatArn({ - service: "bedrock", - resource: "agent", - resourceName: "*", + 'aws:SourceArn': cdk.Stack.of(this).formatArn({ + service: 'bedrock', + resource: 'agent', + resourceName: '*', arnFormat: cdk.ArnFormat.SLASH_RESOURCE_NAME, }), }, }, - }) + }), ); } - this.model.grantInvoke(this.role); + this.foundationModel.grantInvoke(this.role); - const agent = new bedrock.CfnAgent(this, "Agent", { + const agent = new bedrock.CfnAgent(this, 'Agent', { agentName: this.name, - foundationModel: props.model.invokableArn, + foundationModel: props.foundationModel.invokableArn, instruction: props.instruction, description: props.description, idleSessionTtlInSeconds: props.idleSessionTTL?.toSeconds(), @@ -478,11 +476,11 @@ export class Agent extends Construct { // To allow your agent to request the user for additional information // when trying to complete a task, add this action group this.addActionGroup( - new AgentActionGroup(this, "userInputEnabledActionGroup", { - actionGroupName: "UserInputAction", - parentActionGroupSignature: "AMAZON.UserInput", - actionGroupState: props.enableUserInput ? "ENABLED" : "DISABLED", - }) + new AgentActionGroup(this, 'userInputEnabledActionGroup', { + actionGroupName: 'UserInputAction', + parentActionGroupSignature: 'AMAZON.UserInput', + actionGroupState: props.enableUserInput ? 'ENABLED' : 'DISABLED', + }), ); } @@ -514,13 +512,13 @@ export class Agent extends Construct { */ public addKnowledgeBase(knowledgeBase: KnowledgeBase) { if (!knowledgeBase.instruction) { - throw new Error("Agent Knowledge Bases require instructions."); + throw new Error('Agent Knowledge Bases require instructions.'); } new iam.Policy(this, `AgentKBPolicy-${knowledgeBase.name}`, { roles: [this.role], statements: [ new iam.PolicyStatement({ - actions: ["bedrock:UpdateKnowledgeBase", "bedrock:Retrieve"], + actions: ['bedrock:UpdateKnowledgeBase', 'bedrock:Retrieve'], resources: [knowledgeBase.knowledgeBaseArn], }), ], @@ -542,8 +540,8 @@ export class Agent extends Construct { * Add action group to the agent. */ public addActionGroup(actionGroup: AgentActionGroup) { - actionGroup.actionGroupExecutor?.lambda?.addPermission("AgentLambdaInvocationPolicy", { - principal: new iam.ServicePrincipal("bedrock.amazonaws.com"), + actionGroup.actionGroupExecutor?.lambda?.addPermission('AgentLambdaInvocationPolicy', { + principal: new iam.ServicePrincipal('bedrock.amazonaws.com'), sourceArn: this.agentArn, sourceAccount: cdk.Stack.of(this).account, }); @@ -593,17 +591,6 @@ export class Agent extends Construct { } } -/** - * Validate that Bedrock Agents can use the selected model. - * - * @internal This is an internal core function and should not be called directly. - */ -// function validateModel(foundationModel: BedrockFoundationModel) { -// if (!foundationModel.supportsAgents) { -// throw new Error(`The model ${foundationModel} is not supported by Bedrock Agents.`); -// } -// } - /** * Validate the inferenceConfiguration of a prompt override. * @@ -611,31 +598,31 @@ export class Agent extends Construct { */ export function validateInferenceConfiguration(inferenceConfiguration: InferenceConfiguration) { if (inferenceConfiguration.topK < 0 || inferenceConfiguration.topK > 500) { - throw new Error("topK must be between 0 and 500"); + throw new Error('topK must be between 0 and 500'); } if (!Number.isInteger(inferenceConfiguration.topK)) { - throw new Error("topK must be an integer"); + throw new Error('topK must be an integer'); } if (inferenceConfiguration.stopSequences.length > 4) { - throw new Error("stopSequences cannot contain more than 4 elements"); + throw new Error('stopSequences cannot contain more than 4 elements'); } if (inferenceConfiguration.maximumLength < 0 || inferenceConfiguration.maximumLength > 4096) { - throw new Error("maximumLength must be between 0 and 4096"); + throw new Error('maximumLength must be between 0 and 4096'); } if (!Number.isInteger(inferenceConfiguration.maximumLength)) { - throw new Error("maximumLength must be an integer"); + throw new Error('maximumLength must be an integer'); } if (inferenceConfiguration.topP < 0 || inferenceConfiguration.topP > 1) { - throw new Error("topP must be between 0 and 1"); + throw new Error('topP must be between 0 and 1'); } if (inferenceConfiguration.temperature < 0 || inferenceConfiguration.temperature > 1) { - throw new Error("temperature must be between 0 and 1"); + throw new Error('temperature must be between 0 and 1'); } } @@ -645,7 +632,7 @@ export function validateInferenceConfiguration(inferenceConfiguration: Inference * @internal This is an internal core function and should not be called directly. */ export function validatePromptOverrideConfiguration( - promptOverrideConfiguration: PromptOverrideConfiguration | undefined + promptOverrideConfiguration: PromptOverrideConfiguration | undefined, ) { if (!promptOverrideConfiguration) { return; @@ -656,7 +643,7 @@ export function validatePromptOverrideConfiguration( promptOverrideConfiguration.promptConfigurations.some((pc) => pc.parserMode !== ParserMode.OVERRIDDEN) ) { throw new Error( - "overrideLambda can only be used if all promptConfigurations have a parserMode value of OVERRIDDEN" + 'overrideLambda can only be used if all promptConfigurations have a parserMode value of OVERRIDDEN', ); } @@ -665,7 +652,7 @@ export function validatePromptOverrideConfiguration( promptOverrideConfiguration.promptConfigurations.some((pc) => pc.parserMode === ParserMode.OVERRIDDEN) ) { throw new Error( - "At least one promptConfiguration has a parserMode value of OVERRIDDEN, but no overrideLambda is specified" + 'At least one promptConfiguration has a parserMode value of OVERRIDDEN, but no overrideLambda is specified', ); } diff --git a/src/cdk-lib/bedrock/data-sources/parsing.ts b/src/cdk-lib/bedrock/data-sources/parsing.ts index 56c21434..068909c2 100644 --- a/src/cdk-lib/bedrock/data-sources/parsing.ts +++ b/src/cdk-lib/bedrock/data-sources/parsing.ts @@ -11,10 +11,10 @@ * and limitations under the License. */ -import { CfnDataSource } from "aws-cdk-lib/aws-bedrock"; -import { PolicyStatement } from "aws-cdk-lib/aws-iam"; -import { DEFAULT_PARSING_PROMPT } from "./default-parsing-prompt"; -import { IInvokable } from "../models"; +import { CfnDataSource } from 'aws-cdk-lib/aws-bedrock'; +import { PolicyStatement } from 'aws-cdk-lib/aws-iam'; +import { DEFAULT_PARSING_PROMPT } from './default-parsing-prompt'; +import { IInvokable } from '../models'; /** * Enum representing the types of parsing strategies available for Amazon Bedrock Knowledge Bases. @@ -23,7 +23,7 @@ enum ParsingStategyType { /** * Uses a Bedrock Foundation Model for advanced parsing of non-textual information from documents. */ - FOUNDATION_MODEL = "BEDROCK_FOUNDATION_MODEL", + FOUNDATION_MODEL = 'BEDROCK_FOUNDATION_MODEL', } /** @@ -75,7 +75,7 @@ export abstract class ParsingStategy { public generatePolicyStatements(): PolicyStatement[] { return [ new PolicyStatement({ - actions: ["bedrock:InvokeModel"], + actions: ['bedrock:InvokeModel'], resources: [props.parsingModel.invokableArn], }), ]; diff --git a/src/cdk-lib/bedrock/index.ts b/src/cdk-lib/bedrock/index.ts index 890ee733..a97272e5 100644 --- a/src/cdk-lib/bedrock/index.ts +++ b/src/cdk-lib/bedrock/index.ts @@ -11,25 +11,25 @@ * and limitations under the License. */ -export * from "./knowledge-base"; -export * from "./agent"; -export * from "./agent-alias"; -export * from "./agent-action-group"; -export * from "./api-schema"; -export * from "./guardrails/guardrail-filters"; -export * from "./guardrails/guardrails"; -export * from "./models"; -export * from "./prompts/prompt"; -export * from "./prompts/prompt-version"; -export * from "./data-sources/base-data-source"; -export * from "./data-sources/chunking"; -export * from "./data-sources/parsing"; -export * from "./data-sources/custom-transformation"; -export * from "./data-sources/web-crawler-data-source"; -export * from "./data-sources/sharepoint-data-source"; -export * from "./data-sources/confluence-data-source"; -export * from "./data-sources/salesforce-data-source"; -export * from "./data-sources/s3-data-source"; -export * from "./inference-profiles/application-inference-profile"; -export * from "./inference-profiles/common"; -export * from "./inference-profiles/cross-region-inference-profile"; +export * from './knowledge-base'; +export * from './agent'; +export * from './agent-alias'; +export * from './agent-action-group'; +export * from './api-schema'; +export * from './guardrails/guardrail-filters'; +export * from './guardrails/guardrails'; +export * from './models'; +export * from './prompts/prompt'; +export * from './prompts/prompt-version'; +export * from './data-sources/base-data-source'; +export * from './data-sources/chunking'; +export * from './data-sources/parsing'; +export * from './data-sources/custom-transformation'; +export * from './data-sources/web-crawler-data-source'; +export * from './data-sources/sharepoint-data-source'; +export * from './data-sources/confluence-data-source'; +export * from './data-sources/salesforce-data-source'; +export * from './data-sources/s3-data-source'; +export * from './inference-profiles/application-inference-profile'; +export * from './inference-profiles/common'; +export * from './inference-profiles/cross-region-inference-profile'; diff --git a/src/cdk-lib/bedrock/inference-profiles/application-inference-profile.ts b/src/cdk-lib/bedrock/inference-profiles/application-inference-profile.ts index d0496c18..46eb148a 100644 --- a/src/cdk-lib/bedrock/inference-profiles/application-inference-profile.ts +++ b/src/cdk-lib/bedrock/inference-profiles/application-inference-profile.ts @@ -10,12 +10,12 @@ * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions * and limitations under the License. */ -import { CfnTag, Arn, ArnFormat } from "aws-cdk-lib"; -import * as bedrock from "aws-cdk-lib/aws-bedrock"; -import { Construct } from "constructs"; -import { IInferenceProfile, InferenceProfileBase, InferenceProfileType } from "./common"; -import { IInvokable } from "../models"; -import { Grant, IGrantable } from "aws-cdk-lib/aws-iam"; +import { CfnTag, Arn, ArnFormat } from 'aws-cdk-lib'; +import * as bedrock from 'aws-cdk-lib/aws-bedrock'; +import { Grant, IGrantable } from 'aws-cdk-lib/aws-iam'; +import { Construct } from 'constructs'; +import { IInferenceProfile, InferenceProfileBase, InferenceProfileType } from './common'; +import { IInvokable } from '../models'; /****************************************************************************** * PROPS FOR NEW CONSTRUCT @@ -82,7 +82,7 @@ export class ApplicationInferenceProfile extends InferenceProfileBase implements public static fromApplicationInferenceProfileAttributes( scope: Construct, id: string, - attrs: ApplicationInferenceProfileAttributes + attrs: ApplicationInferenceProfileAttributes, ): IInferenceProfile { class Import extends InferenceProfileBase { public readonly inferenceProfileArn = attrs.inferenceProfileArn; @@ -97,13 +97,13 @@ export class ApplicationInferenceProfile extends InferenceProfileBase implements * Import a low-level L1 Cfn ApplicationInferenceProfile */ public static fromCfnApplicationInferenceProfile( - CfnApplicationInferenceProfile: bedrock.CfnApplicationInferenceProfile + CfnApplicationInferenceProfile: bedrock.CfnApplicationInferenceProfile, ): IInferenceProfile { return new (class extends InferenceProfileBase { public readonly inferenceProfileArn = CfnApplicationInferenceProfile.attrInferenceProfileArn; public readonly inferenceProfileId = CfnApplicationInferenceProfile.attrInferenceProfileId; public readonly type = InferenceProfileType.APPLICATION; - })(CfnApplicationInferenceProfile, "@FromCfnApplicationInferenceProfile"); + })(CfnApplicationInferenceProfile, '@FromCfnApplicationInferenceProfile'); } /** * The name of the application inference profile. @@ -184,7 +184,31 @@ export class ApplicationInferenceProfile extends InferenceProfileBase implements * Gives the appropriate policies to invoke and use the Foundation Model. */ public grantInvoke(grantee: IGrantable): Grant { - this.inferenceProfileModel.grantInvoke(grantee); + + // for CRIS, we need to provide permissions to invoke + // the model in all regions where the inference profile + // can route requests. Since we manipulate a inferenceProfileModel + // which is a IInvokable, we don't have the model Id available. + // To get this information back, we split the existing Arn, and update + // the regions + const splitted = Arn.split(this.inferenceProfileModel.invokableArn, ArnFormat.SLASH_RESOURCE_NAME); + + const invokableArn = Arn.format({ + partition: splitted.partition, + service: splitted.service, + region: '*', + account: '', + resource: splitted.resource, + resourceName: splitted.resourceName, + arnFormat: ArnFormat.SLASH_RESOURCE_NAME, + }); + + Grant.addToPrincipal({ + grantee: grantee, + actions: ['bedrock:InvokeModel'], + resourceArns: [invokableArn], + }); + return this.grantProfileUsage(grantee); } @@ -195,7 +219,7 @@ export class ApplicationInferenceProfile extends InferenceProfileBase implements grantProfileUsage(grantee: IGrantable): Grant { const grant = Grant.addToPrincipal({ grantee: grantee, - actions: ["bedrock:GetInferenceProfile", "bedrock:InvokeModel"], + actions: ['bedrock:GetInferenceProfile', 'bedrock:InvokeModel'], resourceArns: [this.inferenceProfileArn], }); return grant; diff --git a/src/cdk-lib/bedrock/inference-profiles/common.ts b/src/cdk-lib/bedrock/inference-profiles/common.ts index e12f03f1..f366a371 100644 --- a/src/cdk-lib/bedrock/inference-profiles/common.ts +++ b/src/cdk-lib/bedrock/inference-profiles/common.ts @@ -10,8 +10,8 @@ * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions * and limitations under the License. */ -import { IResource, Resource } from "aws-cdk-lib"; -import { Grant, IGrantable } from "aws-cdk-lib/aws-iam"; +import { IResource, Resource } from 'aws-cdk-lib'; +import { Grant, IGrantable } from 'aws-cdk-lib/aws-iam'; /** These are the values used by the API when using aws bedrock get-inference-profile --inference-profile-identifier XXXXXXX */ export enum InferenceProfileType { @@ -19,12 +19,12 @@ export enum InferenceProfileType { * An inference profile that is created by AWS. These are profiles such as cross-region * which help you distributed traffic across a geographic region. */ - SYSTEM_DEFINED = "SYSTEM_DEFINED", + SYSTEM_DEFINED = 'SYSTEM_DEFINED', /** * An inference profile that is user-created. These are profiles that help * you track costs or metrics. */ - APPLICATION = "APPLICATION", + APPLICATION = 'APPLICATION', } /****************************************************************************** @@ -78,7 +78,7 @@ export abstract class InferenceProfileBase extends Resource implements IInferenc grantProfileUsage(grantee: IGrantable): Grant { const grant = Grant.addToPrincipal({ grantee: grantee, - actions: ["bedrock:GetInferenceProfile", "bedrock:ListInferenceProfiles"], + actions: ['bedrock:GetInferenceProfile', 'bedrock:ListInferenceProfiles'], resourceArns: [this.inferenceProfileArn], scope: this, }); diff --git a/src/cdk-lib/bedrock/inference-profiles/cross-region-inference-profile.ts b/src/cdk-lib/bedrock/inference-profiles/cross-region-inference-profile.ts index 2abb9665..52776475 100644 --- a/src/cdk-lib/bedrock/inference-profiles/cross-region-inference-profile.ts +++ b/src/cdk-lib/bedrock/inference-profiles/cross-region-inference-profile.ts @@ -1,21 +1,33 @@ -import { Arn, ArnFormat, Aws } from "aws-cdk-lib"; -import { BedrockFoundationModel, IInvokable } from "../models"; -import { IInferenceProfile, InferenceProfileType } from "./common"; -import { Grant, IGrantable } from "aws-cdk-lib/aws-iam"; +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance + * with the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES + * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ +import { Arn, ArnFormat, Aws } from 'aws-cdk-lib'; +import { Grant, IGrantable } from 'aws-cdk-lib/aws-iam'; +import { BedrockFoundationModel, IInvokable } from '../models'; +import { IInferenceProfile, InferenceProfileType } from './common'; export enum CrossRegionInferenceProfileRegion { /** * EU: Frankfurt (eu-central-1), Ireland (eu-west-1), Paris (eu-west-3) */ - EU = "eu", + EU = 'eu', /** * US: N. Virginia (us-east-1), Oregon (us-west-2) */ - US = "us", + US = 'us', /** * This might include: ap-northeast-1, ap-northeast-2, ap-south-1, ap-southeast-1, and ap-southeast-2 */ - APAC = "apac", + APAC = 'apac', } /****************************************************************************** @@ -70,10 +82,10 @@ export class CrossRegionInferenceProfile implements IInvokable, IInferenceProfil this.inferenceProfileId = `${props.geoRegion}.${props.model.modelId}`; this.inferenceProfileArn = Arn.format({ partition: Aws.PARTITION, - service: "bedrock", + service: 'bedrock', account: Aws.ACCOUNT_ID, region: Aws.REGION, - resource: "inference-profile", + resource: 'inference-profile', resourceName: this.inferenceProfileId, arnFormat: ArnFormat.SLASH_RESOURCE_NAME, }); @@ -85,6 +97,26 @@ export class CrossRegionInferenceProfile implements IInvokable, IInferenceProfil * Gives the appropriate policies to invoke and use the Foundation Model. */ public grantInvoke(grantee: IGrantable): Grant { + + // for CRIS, we need to provide permissions to invoke + // the model in all regions where the inference profile + // can route requests + const invokableArn = Arn.format({ + partition: Aws.PARTITION, + service: 'bedrock', + region: '*', + account: '', + resource: 'foundation-model', + resourceName: this.inferenceProfileModel.modelId, + arnFormat: ArnFormat.SLASH_RESOURCE_NAME, + }); + + Grant.addToPrincipal({ + grantee: grantee, + actions: ['bedrock:InvokeModel'], + resourceArns: [invokableArn], + }); + this.inferenceProfileModel.grantInvoke(grantee); return this.grantProfileUsage(grantee); } @@ -96,7 +128,7 @@ export class CrossRegionInferenceProfile implements IInvokable, IInferenceProfil grantProfileUsage(grantee: IGrantable): Grant { const grant = Grant.addToPrincipal({ grantee: grantee, - actions: ["bedrock:GetInferenceProfile", "bedrock:InvokeModel"], + actions: ['bedrock:GetInferenceProfile', 'bedrock:InvokeModel'], resourceArns: [this.inferenceProfileArn], }); return grant; diff --git a/src/cdk-lib/bedrock/models.ts b/src/cdk-lib/bedrock/models.ts index 299a8681..c48dd035 100644 --- a/src/cdk-lib/bedrock/models.ts +++ b/src/cdk-lib/bedrock/models.ts @@ -11,10 +11,10 @@ * and limitations under the License. */ -import { Arn, ArnFormat, Aws } from "aws-cdk-lib"; -import { IModel } from "aws-cdk-lib/aws-bedrock"; -import { Grant, IGrantable } from "aws-cdk-lib/aws-iam"; -import { IConstruct } from "constructs"; +import { Arn, ArnFormat, Aws } from 'aws-cdk-lib'; +import { IModel, FoundationModel, FoundationModelIdentifier } from 'aws-cdk-lib/aws-bedrock'; +import { Grant, IGrantable } from 'aws-cdk-lib/aws-iam'; +import { IConstruct } from 'constructs'; /** * Represents an Amazon Bedrock abstraction on which you can @@ -68,30 +68,30 @@ export class BedrockFoundationModel implements IInvokable { /**************************************************************************** * AMAZON ***************************************************************************/ - public static readonly AMAZON_TITAN_TEXT_EXPRESS_V1 = new BedrockFoundationModel("amazon.titan-text-express-v1", { + public static readonly AMAZON_TITAN_TEXT_EXPRESS_V1 = new BedrockFoundationModel('amazon.titan-text-express-v1', { supportsAgents: true, }); - public static readonly AMAZON_TITAN_PREMIER_V1_0 = new BedrockFoundationModel("amazon.titan-text-premier-v1:0", { + public static readonly AMAZON_TITAN_PREMIER_V1_0 = new BedrockFoundationModel('amazon.titan-text-premier-v1:0', { supportsAgents: true, }); - public static readonly TITAN_EMBED_TEXT_V1 = new BedrockFoundationModel("amazon.titan-embed-text-v1", { + public static readonly TITAN_EMBED_TEXT_V1 = new BedrockFoundationModel('amazon.titan-embed-text-v1', { supportsKnowledgeBase: true, vectorDimensions: 1536, }); - public static readonly TITAN_EMBED_TEXT_V2_1024 = new BedrockFoundationModel("amazon.titan-embed-text-v2:0", { + public static readonly TITAN_EMBED_TEXT_V2_1024 = new BedrockFoundationModel('amazon.titan-embed-text-v2:0', { supportsKnowledgeBase: true, vectorDimensions: 1024, }); - public static readonly TITAN_EMBED_TEXT_V2_512 = new BedrockFoundationModel("amazon.titan-embed-text-v2:0", { + public static readonly TITAN_EMBED_TEXT_V2_512 = new BedrockFoundationModel('amazon.titan-embed-text-v2:0', { supportsKnowledgeBase: true, vectorDimensions: 512, }); - public static readonly TITAN_EMBED_TEXT_V2_256 = new BedrockFoundationModel("amazon.titan-embed-text-v2:0", { + public static readonly TITAN_EMBED_TEXT_V2_256 = new BedrockFoundationModel('amazon.titan-embed-text-v2:0', { supportsKnowledgeBase: true, vectorDimensions: 256, }); @@ -99,56 +99,56 @@ export class BedrockFoundationModel implements IInvokable { * ANTHROPIC ***************************************************************************/ public static readonly ANTHROPIC_CLAUDE_3_5_SONNET_V2_0 = new BedrockFoundationModel( - "anthropic.claude-3-5-sonnet-20241022-v2:0", - { supportsAgents: true, supportsCrossRegion: true } + 'anthropic.claude-3-5-sonnet-20241022-v2:0', + { supportsAgents: true, supportsCrossRegion: true }, ); public static readonly ANTHROPIC_CLAUDE_3_5_SONNET_V1_0 = new BedrockFoundationModel( - "anthropic.claude-3-5-sonnet-20240620-v1:0", - { supportsAgents: true, supportsCrossRegion: true } + 'anthropic.claude-3-5-sonnet-20240620-v1:0', + { supportsAgents: true, supportsCrossRegion: true }, ); public static readonly ANTHROPIC_CLAUDE_3_5_HAIKU_V1_0 = new BedrockFoundationModel( - "anthropic.claude-3-5-haiku-20241022-v1:0", - { supportsAgents: true, supportsCrossRegion: true } + 'anthropic.claude-3-5-haiku-20241022-v1:0', + { supportsAgents: true, supportsCrossRegion: true }, ); public static readonly ANTHROPIC_CLAUDE_OPUS_V1_0 = new BedrockFoundationModel( - "anthropic.claude-3-opus-20240229-v1:0", - { supportsAgents: true } + 'anthropic.claude-3-opus-20240229-v1:0', + { supportsAgents: true }, ); public static readonly ANTHROPIC_CLAUDE_SONNET_V1_0 = new BedrockFoundationModel( - "anthropic.claude-3-sonnet-20240229-v1:0", - { supportsAgents: true, supportsCrossRegion: true } + 'anthropic.claude-3-sonnet-20240229-v1:0', + { supportsAgents: true, supportsCrossRegion: true }, ); public static readonly ANTHROPIC_CLAUDE_HAIKU_V1_0 = new BedrockFoundationModel( - "anthropic.claude-3-haiku-20240307-v1:0", - { supportsAgents: true, supportsCrossRegion: true } + 'anthropic.claude-3-haiku-20240307-v1:0', + { supportsAgents: true, supportsCrossRegion: true }, ); - public static readonly ANTHROPIC_CLAUDE_V2_1 = new BedrockFoundationModel("anthropic.claude-v2:1", { + public static readonly ANTHROPIC_CLAUDE_V2_1 = new BedrockFoundationModel('anthropic.claude-v2:1', { supportsAgents: true, }); - public static readonly ANTHROPIC_CLAUDE_V2 = new BedrockFoundationModel("anthropic.claude-v2", { + public static readonly ANTHROPIC_CLAUDE_V2 = new BedrockFoundationModel('anthropic.claude-v2', { supportsAgents: true, }); - public static readonly ANTHROPIC_CLAUDE_INSTANT_V1_2 = new BedrockFoundationModel("anthropic.claude-instant-v1", { + public static readonly ANTHROPIC_CLAUDE_INSTANT_V1_2 = new BedrockFoundationModel('anthropic.claude-instant-v1', { supportsAgents: true, }); /**************************************************************************** * COHERE ***************************************************************************/ - public static readonly COHERE_EMBED_ENGLISH_V3 = new BedrockFoundationModel("cohere.embed-english-v3", { + public static readonly COHERE_EMBED_ENGLISH_V3 = new BedrockFoundationModel('cohere.embed-english-v3', { supportsKnowledgeBase: true, vectorDimensions: 1024, }); - public static readonly COHERE_EMBED_MULTILINGUAL_V3 = new BedrockFoundationModel("cohere.embed-multilingual-v3", { + public static readonly COHERE_EMBED_MULTILINGUAL_V3 = new BedrockFoundationModel('cohere.embed-multilingual-v3', { supportsKnowledgeBase: true, vectorDimensions: 1024, }); @@ -157,20 +157,27 @@ export class BedrockFoundationModel implements IInvokable { * META ***************************************************************************/ public static readonly META_LLAMA_3_2_11B_INSTRUCT_V1 = new BedrockFoundationModel( - "meta.llama3-2-11b-instruct-v1:0", + 'meta.llama3-2-11b-instruct-v1:0', { supportsCrossRegion: true, - } + }, ); - public static readonly META_LLAMA_3_2_3B_INSTRUCT_V1 = new BedrockFoundationModel("meta.llama3-2-3b-instruct-v1:0", { + public static readonly META_LLAMA_3_2_3B_INSTRUCT_V1 = new BedrockFoundationModel('meta.llama3-2-3b-instruct-v1:0', { supportsCrossRegion: true, }); - public static readonly META_LLAMA_3_2_1B_INSTRUCT_V1 = new BedrockFoundationModel("meta.llama3-2-1b-instruct-v1:0", { + public static readonly META_LLAMA_3_2_1B_INSTRUCT_V1 = new BedrockFoundationModel('meta.llama3-2-1b-instruct-v1:0', { supportsCrossRegion: true, }); + public static fromCdkFoundationModelId(modelId: FoundationModelIdentifier, props: BedrockFoundationModelProps = {}): BedrockFoundationModel { + return new BedrockFoundationModel(modelId.modelId, props); + } + public static fromCdkFoundationModel(modelId: FoundationModel, props: BedrockFoundationModelProps = {}): BedrockFoundationModel { + return new BedrockFoundationModel(modelId.modelId, props); + } + /**************************************************************************** * Constructor ***************************************************************************/ @@ -185,10 +192,10 @@ export class BedrockFoundationModel implements IInvokable { this.modelId = value; this.modelArn = Arn.format({ partition: Aws.PARTITION, - service: "bedrock", + service: 'bedrock', region: Aws.REGION, - account: Aws.ACCOUNT_ID, - resource: "foundation-model", + account: '', + resource: 'foundation-model', resourceName: this.modelId, arnFormat: ArnFormat.SLASH_RESOURCE_NAME, }); @@ -225,7 +232,7 @@ export class BedrockFoundationModel implements IInvokable { public grantInvoke(grantee: IGrantable): Grant { const grant = Grant.addToPrincipal({ grantee: grantee, - actions: ["bedrock:InvokeModel"], + actions: ['bedrock:InvokeModel'], resourceArns: [this.invokableArn], }); return grant; diff --git a/src/cdk-lib/bedrock/prompts/prompt.ts b/src/cdk-lib/bedrock/prompts/prompt.ts index 6924bd42..1a9b2a3e 100644 --- a/src/cdk-lib/bedrock/prompts/prompt.ts +++ b/src/cdk-lib/bedrock/prompts/prompt.ts @@ -11,15 +11,15 @@ * and limitations under the License. */ -import { Arn, ArnFormat, aws_kms as kms, Lazy, aws_bedrock as bedrock, Resource } from "aws-cdk-lib"; -import { Grant, IGrantable } from "aws-cdk-lib/aws-iam"; -import { IKey } from "aws-cdk-lib/aws-kms"; -import { md5hash } from "aws-cdk-lib/core/lib/helpers-internal"; -import { Construct } from "constructs"; -import { IInvokable } from "../models"; +import { Arn, ArnFormat, aws_kms as kms, Lazy, aws_bedrock as bedrock, Resource } from 'aws-cdk-lib'; +import { Grant, IGrantable } from 'aws-cdk-lib/aws-iam'; +import { IKey } from 'aws-cdk-lib/aws-kms'; +import { md5hash } from 'aws-cdk-lib/core/lib/helpers-internal'; +import { Construct } from 'constructs'; +import { IInvokable } from '../models'; export enum PromptTemplateType { - TEXT = "TEXT", + TEXT = 'TEXT', } export interface CommonPromptVariantProps { @@ -155,7 +155,7 @@ export abstract class PromptBase extends Resource implements IPrompt { return Grant.addToPrincipal({ grantee, resourceArns: [this.promptArn], - actions: ["bedrock:GetPrompt"], + actions: ['bedrock:GetPrompt'], scope: this, }); } @@ -232,7 +232,7 @@ export class Prompt extends Construct implements IPrompt { class Import extends PromptBase { public readonly promptArn = attrs.promptArn; public readonly promptId = formattedArn.resourceName!; - public readonly promptVersion = attrs.promptVersion ?? "DRAFT"; + public readonly promptVersion = attrs.promptVersion ?? 'DRAFT'; public readonly kmsKey = attrs.kmsKey; } @@ -314,7 +314,7 @@ export class Prompt extends Construct implements IPrompt { // ------------------------------------------------------ // L1 Instantiation // ------------------------------------------------------ - this._resource = new bedrock.CfnPrompt(this, "Prompt", cfnProps); + this._resource = new bedrock.CfnPrompt(this, 'Prompt', cfnProps); this.promptArn = this._resource.attrArn; this.promptId = this._resource.attrId; @@ -334,7 +334,7 @@ export class Prompt extends Construct implements IPrompt { const matchesPattern = /^([0-9a-zA-Z][_-]?){1,100}$/.test(this.promptName); if (!matchesPattern) { errors.push( - "Valid characters are a-z, A-Z, 0-9, _ (underscore) and - (hyphen). And must not begin with a hyphen" + 'Valid characters are a-z, A-Z, 0-9, _ (underscore) and - (hyphen). And must not begin with a hyphen', ); } if (errors.length > 0) { @@ -350,7 +350,7 @@ export class Prompt extends Construct implements IPrompt { const errors: string[] = []; if (this.variants.length > 3) { errors.push( - `Error: Too many variants specified. The maximum allowed is 3, but you have provided ${this.variants.length} variants.` + `Error: Too many variants specified. The maximum allowed is 3, but you have provided ${this.variants.length} variants.`, ); } return errors; diff --git a/test/cdk-lib/bedrock/data-sources/s3-data-source.test.ts b/test/cdk-lib/bedrock/data-sources/s3-data-source.test.ts index 77e0258e..6161f056 100644 --- a/test/cdk-lib/bedrock/data-sources/s3-data-source.test.ts +++ b/test/cdk-lib/bedrock/data-sources/s3-data-source.test.ts @@ -11,15 +11,15 @@ * and limitations under the License. */ -import * as cdk from "aws-cdk-lib"; -import { Template, Match } from "aws-cdk-lib/assertions"; -import { Code, Function, Runtime } from "aws-cdk-lib/aws-lambda"; -import * as s3 from "aws-cdk-lib/aws-s3"; -import { AwsSolutionsChecks } from "cdk-nag"; -import * as bedrock from "../../../../src/cdk-lib/bedrock"; -import * as foundationModels from "../../../../src/cdk-lib/bedrock/models"; +import * as cdk from 'aws-cdk-lib'; +import { Template, Match } from 'aws-cdk-lib/assertions'; +import { Code, Function, Runtime } from 'aws-cdk-lib/aws-lambda'; +import * as s3 from 'aws-cdk-lib/aws-s3'; +import { AwsSolutionsChecks } from 'cdk-nag'; +import * as bedrock from '../../../../src/cdk-lib/bedrock'; +import * as foundationModels from '../../../../src/cdk-lib/bedrock/models'; -describe("S3 Data Source", () => { +describe('S3 Data Source', () => { let stack: cdk.Stack; let bucket: s3.Bucket; let kb: bedrock.KnowledgeBase; @@ -27,46 +27,46 @@ describe("S3 Data Source", () => { beforeEach(() => { const app = new cdk.App(); cdk.Aspects.of(app).add(new AwsSolutionsChecks()); - stack = new cdk.Stack(app, "TestStack"); - bucket = new s3.Bucket(stack, "TestBucket"); - kb = new bedrock.KnowledgeBase(stack, "KB", { + stack = new cdk.Stack(app, 'TestStack'); + bucket = new s3.Bucket(stack, 'TestBucket'); + kb = new bedrock.KnowledgeBase(stack, 'KB', { embeddingsModel: foundationModels.BedrockFoundationModel.TITAN_EMBED_TEXT_V2_1024, }); }); - test("Method", () => { + test('Method', () => { kb.addS3DataSource({ bucket, - dataSourceName: "TestDataSource", + dataSourceName: 'TestDataSource', }); - Template.fromStack(stack).hasResourceProperties("AWS::Bedrock::DataSource", { + Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::DataSource', { KnowledgeBaseId: { - "Fn::GetAtt": [Match.anyValue(), "KnowledgeBaseId"], + 'Fn::GetAtt': [Match.anyValue(), 'KnowledgeBaseId'], }, - Name: "TestDataSource", + Name: 'TestDataSource', DataSourceConfiguration: { S3Configuration: { BucketArn: { - "Fn::GetAtt": [Match.anyValue(), "Arn"], + 'Fn::GetAtt': [Match.anyValue(), 'Arn'], }, }, }, }); }); - test("Default chunking", () => { - new bedrock.S3DataSource(stack, "TestDataSource", { + test('Default chunking', () => { + new bedrock.S3DataSource(stack, 'TestDataSource', { bucket, knowledgeBase: kb, - dataSourceName: "TestDataSource", + dataSourceName: 'TestDataSource', chunkingStrategy: bedrock.ChunkingStrategy.DEFAULT, }); - Template.fromStack(stack).hasResourceProperties("AWS::Bedrock::DataSource", { + Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::DataSource', { VectorIngestionConfiguration: { ChunkingConfiguration: { - ChunkingStrategy: "FIXED_SIZE", + ChunkingStrategy: 'FIXED_SIZE', FixedSizeChunkingConfiguration: { MaxTokens: 300, OverlapPercentage: 20, @@ -76,21 +76,21 @@ describe("S3 Data Source", () => { }); }); - test("Fixed size chunking", () => { - new bedrock.S3DataSource(stack, "TestDataSource", { + test('Fixed size chunking', () => { + new bedrock.S3DataSource(stack, 'TestDataSource', { bucket, knowledgeBase: kb, - dataSourceName: "TestDataSource", + dataSourceName: 'TestDataSource', chunkingStrategy: bedrock.ChunkingStrategy.fixedSize({ maxTokens: 1024, overlapPercentage: 20, }), }); - Template.fromStack(stack).hasResourceProperties("AWS::Bedrock::DataSource", { + Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::DataSource', { VectorIngestionConfiguration: { ChunkingConfiguration: { - ChunkingStrategy: "FIXED_SIZE", + ChunkingStrategy: 'FIXED_SIZE', FixedSizeChunkingConfiguration: { MaxTokens: 1024, OverlapPercentage: 20, @@ -100,33 +100,33 @@ describe("S3 Data Source", () => { }); }); - test("No chunking", () => { - new bedrock.S3DataSource(stack, "TestDataSource", { + test('No chunking', () => { + new bedrock.S3DataSource(stack, 'TestDataSource', { bucket, knowledgeBase: kb, - dataSourceName: "TestDataSource", + dataSourceName: 'TestDataSource', chunkingStrategy: bedrock.ChunkingStrategy.NONE, }); - Template.fromStack(stack).hasResourceProperties("AWS::Bedrock::DataSource", { + Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::DataSource', { VectorIngestionConfiguration: { - ChunkingConfiguration: { ChunkingStrategy: "NONE" }, + ChunkingConfiguration: { ChunkingStrategy: 'NONE' }, }, }); }); - test("Semantic chunking - default", () => { - new bedrock.S3DataSource(stack, "TestDataSource", { + test('Semantic chunking - default', () => { + new bedrock.S3DataSource(stack, 'TestDataSource', { bucket, knowledgeBase: kb, - dataSourceName: "TestDataSource", + dataSourceName: 'TestDataSource', chunkingStrategy: bedrock.ChunkingStrategy.SEMANTIC, }); - Template.fromStack(stack).hasResourceProperties("AWS::Bedrock::DataSource", { + Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::DataSource', { VectorIngestionConfiguration: { ChunkingConfiguration: { - ChunkingStrategy: "SEMANTIC", + ChunkingStrategy: 'SEMANTIC', SemanticChunkingConfiguration: { MaxTokens: 300, BufferSize: 0, @@ -137,11 +137,11 @@ describe("S3 Data Source", () => { }); }); - test("Semantic chunking", () => { - new bedrock.S3DataSource(stack, "TestDataSource", { + test('Semantic chunking', () => { + new bedrock.S3DataSource(stack, 'TestDataSource', { bucket, knowledgeBase: kb, - dataSourceName: "TestDataSource", + dataSourceName: 'TestDataSource', chunkingStrategy: bedrock.ChunkingStrategy.semantic({ maxTokens: 1024, bufferSize: 1, @@ -149,10 +149,10 @@ describe("S3 Data Source", () => { }), }); - Template.fromStack(stack).hasResourceProperties("AWS::Bedrock::DataSource", { + Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::DataSource', { VectorIngestionConfiguration: { ChunkingConfiguration: { - ChunkingStrategy: "SEMANTIC", + ChunkingStrategy: 'SEMANTIC', SemanticChunkingConfiguration: { MaxTokens: 1024, BufferSize: 1, @@ -163,18 +163,18 @@ describe("S3 Data Source", () => { }); }); - test("Hierarchical chunking - default", () => { - new bedrock.S3DataSource(stack, "TestDataSource", { + test('Hierarchical chunking - default', () => { + new bedrock.S3DataSource(stack, 'TestDataSource', { bucket, knowledgeBase: kb, - dataSourceName: "TestDataSource", + dataSourceName: 'TestDataSource', chunkingStrategy: bedrock.ChunkingStrategy.HIERARCHICAL_TITAN, }); - Template.fromStack(stack).hasResourceProperties("AWS::Bedrock::DataSource", { + Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::DataSource', { VectorIngestionConfiguration: { ChunkingConfiguration: { - ChunkingStrategy: "HIERARCHICAL", + ChunkingStrategy: 'HIERARCHICAL', HierarchicalChunkingConfiguration: { LevelConfigurations: [ { MaxTokens: 1500 }, // Parent max tokens @@ -187,11 +187,11 @@ describe("S3 Data Source", () => { }); }); - test("Hierarchical chunking - custom", () => { - new bedrock.S3DataSource(stack, "TestDataSource", { + test('Hierarchical chunking - custom', () => { + new bedrock.S3DataSource(stack, 'TestDataSource', { bucket, knowledgeBase: kb, - dataSourceName: "TestDataSource", + dataSourceName: 'TestDataSource', chunkingStrategy: bedrock.ChunkingStrategy.hierarchical({ maxParentTokenSize: 1024, maxChildTokenSize: 256, @@ -199,10 +199,10 @@ describe("S3 Data Source", () => { }), }); - Template.fromStack(stack).hasResourceProperties("AWS::Bedrock::DataSource", { + Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::DataSource', { VectorIngestionConfiguration: { ChunkingConfiguration: { - ChunkingStrategy: "HIERARCHICAL", + ChunkingStrategy: 'HIERARCHICAL', HierarchicalChunkingConfiguration: { LevelConfigurations: [ { MaxTokens: 1024 }, // Parent max tokens @@ -215,24 +215,24 @@ describe("S3 Data Source", () => { }); }); - test("FM parsing", () => { - new bedrock.S3DataSource(stack, "TestDataSource", { + test('FM parsing', () => { + new bedrock.S3DataSource(stack, 'TestDataSource', { bucket, knowledgeBase: kb, - dataSourceName: "TestDataSource", + dataSourceName: 'TestDataSource', parsingStrategy: bedrock.ParsingStategy.foundationModel({ parsingModel: foundationModels.BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0, }), }); - Template.fromStack(stack).hasResourceProperties("AWS::Bedrock::DataSource", { + Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::DataSource', { VectorIngestionConfiguration: { ParsingConfiguration: { - ParsingStrategy: "BEDROCK_FOUNDATION_MODEL", + ParsingStrategy: 'BEDROCK_FOUNDATION_MODEL', BedrockFoundationModelConfiguration: { ModelArn: Match.anyValue(), ParsingPrompt: { - ParsingPromptText: Match.stringLikeRegexp("Transcribe the text content.*"), + ParsingPromptText: Match.stringLikeRegexp('Transcribe the text content.*'), }, }, }, @@ -240,20 +240,20 @@ describe("S3 Data Source", () => { }); }); - test("Lambda Transformation", () => { + test('Lambda Transformation', () => { // WHEN - const bucket2 = new s3.Bucket(stack, "mybucket", { - bucketName: "mybucketname", + const bucket2 = new s3.Bucket(stack, 'mybucket', { + bucketName: 'mybucketname', }); - const lambdaFunction = new Function(stack, "myFunction", { + const lambdaFunction = new Function(stack, 'myFunction', { code: Code.fromInline('exports.handler = function(event, ctx, cb) { return cb(null, "hello"); }'), - handler: "index.handler", + handler: 'index.handler', runtime: Runtime.PYTHON_3_11, }); - new bedrock.S3DataSource(stack, "TestDataSource", { + new bedrock.S3DataSource(stack, 'TestDataSource', { bucket, knowledgeBase: kb, - dataSourceName: "TestDataSource", + dataSourceName: 'TestDataSource', customTransformation: bedrock.CustomTransformation.lambda({ lambdaFunction, s3BucketUri: `s3://${bucket2.bucketName}/chunkprocessor`, @@ -261,16 +261,16 @@ describe("S3 Data Source", () => { }); // THEN - Template.fromStack(stack).hasResourceProperties("AWS::Bedrock::DataSource", { + Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::DataSource', { VectorIngestionConfiguration: { CustomTransformationConfiguration: { Transformations: [ { - StepToApply: "POST_CHUNKING", + StepToApply: 'POST_CHUNKING', TransformationFunction: { TransformationLambdaConfiguration: { LambdaArn: { - "Fn::GetAtt": [Match.anyValue(), "Arn"], + 'Fn::GetAtt': [Match.anyValue(), 'Arn'], }, }, }, diff --git a/test/cdk-lib/bedrock/inference-profile.test.ts b/test/cdk-lib/bedrock/inference-profile.test.ts index a4504326..3583657b 100644 --- a/test/cdk-lib/bedrock/inference-profile.test.ts +++ b/test/cdk-lib/bedrock/inference-profile.test.ts @@ -10,197 +10,174 @@ * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions * and limitations under the License. */ -import * as cdk from "aws-cdk-lib"; -import { Match, Template } from "aws-cdk-lib/assertions"; -import { CfnApplicationInferenceProfile } from "aws-cdk-lib/aws-bedrock"; -import { AwsSolutionsChecks } from "cdk-nag"; -import * as bedrock from "../../../src/cdk-lib/bedrock"; +import * as cdk from 'aws-cdk-lib'; +import { Match, Template } from 'aws-cdk-lib/assertions'; +import { CfnApplicationInferenceProfile } from 'aws-cdk-lib/aws-bedrock'; +import { AwsSolutionsChecks } from 'cdk-nag'; +import * as bedrock from '../../../src/cdk-lib/bedrock'; -describe("CDK-Created-Cross-Region-Inference-Profile", () => { +describe('CDK-Created-Cross-Region-Inference-Profile', () => { let stack: cdk.Stack; beforeEach(() => { const app = new cdk.App(); cdk.Aspects.of(app).add(new AwsSolutionsChecks()); - stack = new cdk.Stack(app, "TestStack"); + stack = new cdk.Stack(app, 'TestStack'); }); - test("Basic Creation", () => { - new bedrock.CrossRegionInferenceProfile(stack, "TestAIP", { + test('Basic Creation', () => { + const cris = bedrock.CrossRegionInferenceProfile.fromConfig({ geoRegion: bedrock.CrossRegionInferenceProfileRegion.EU, model: bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0, }); - Template.fromStack(stack).hasResourceProperties("AWS::Bedrock::ApplicationInferenceProfile", { - InferenceProfileName: "TestAIP", - Description: "This is a test application inf profile", - ModelSource: { - CopyFrom: { - "Fn::Join": [ - "", - [ - "arn:aws:bedrock:", - { - Ref: "AWS::Region", - }, - "::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0", - ], - ], - }, - }, - Tags: [ - { - Key: "test-key", - Value: "test-value", - }, - ], - }); + expect(cris.inferenceProfileArn).toBe('cew2pa5r8hog'); }); - test("Basic Creation with a system defined inference profile", () => { - new bedrock.ApplicationInferenceProfile(stack, "TestAIPSystem", { - inferenceProfileName: "TestAIPSystem", + test('Basic Creation with a system defined inference profile', () => { + new bedrock.ApplicationInferenceProfile(stack, 'TestAIPSystem', { + inferenceProfileName: 'TestAIPSystem', modelSource: bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_3_5_SONNET_V2_0, }); - Template.fromStack(stack).hasResourceProperties("AWS::Bedrock::ApplicationInferenceProfile", { - InferenceProfileName: "TestAIPSystem", + Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::ApplicationInferenceProfile', { + InferenceProfileName: 'TestAIPSystem', Description: Match.absent(), ModelSource: { - CopyFrom: "arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0", + CopyFrom: 'arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0', }, }); }); - test("Basic Creation", () => { - new bedrock.ApplicationInferenceProfile(stack, "TestAIPSystem", { - inferenceProfileName: "TestAIPSystem", - modelSource: new bedrock.CrossRegionInferenceProfile(stack, "CrossRegion", { + test('Basic Creation', () => { + new bedrock.ApplicationInferenceProfile(stack, 'TestAIPSystem', { + inferenceProfileName: 'TestAIPSystem', + modelSource: bedrock.CrossRegionInferenceProfile.fromConfig({ model: bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_3_5_SONNET_V2_0, geoRegion: bedrock.CrossRegionInferenceProfileRegion.EU, }), - tags: [{ key: "project", value: "test" }], + tags: [{ key: 'project', value: 'test' }], }); - Template.fromStack(stack).hasResourceProperties("AWS::Bedrock::ApplicationInferenceProfile", { - InferenceProfileName: "TestAIPSystem", + Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::ApplicationInferenceProfile', { + InferenceProfileName: 'TestAIPSystem', Description: Match.absent(), ModelSource: { - CopyFrom: "arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0", + CopyFrom: 'arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0', }, }); }); }); -describe("CDK-Created-Application-Inference-Profile", () => { +describe('CDK-Created-Application-Inference-Profile', () => { let stack: cdk.Stack; beforeEach(() => { const app = new cdk.App(); cdk.Aspects.of(app).add(new AwsSolutionsChecks()); - stack = new cdk.Stack(app, "TestStack"); + stack = new cdk.Stack(app, 'TestStack'); }); - test("Basic Creation with a foundation model", () => { - new bedrock.ApplicationInferenceProfile(stack, "TestAIP", { - inferenceProfileName: "TestAIP", - description: "This is a test application inf profile", + test('Basic Creation with a foundation model', () => { + new bedrock.ApplicationInferenceProfile(stack, 'TestAIP', { + inferenceProfileName: 'TestAIP', + description: 'This is a test application inf profile', modelSource: bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0, - tags: [{ key: "test-key", value: "test-value" }], + tags: [{ key: 'test-key', value: 'test-value' }], }); - Template.fromStack(stack).hasResourceProperties("AWS::Bedrock::ApplicationInferenceProfile", { - InferenceProfileName: "TestAIP", - Description: "This is a test application inf profile", + Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::ApplicationInferenceProfile', { + InferenceProfileName: 'TestAIP', + Description: 'This is a test application inf profile', ModelSource: { CopyFrom: { - "Fn::Join": [ - "", + 'Fn::Join': [ + '', [ - "arn:aws:bedrock:", + 'arn:aws:bedrock:', { - Ref: "AWS::Region", + Ref: 'AWS::Region', }, - "::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0", + '::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0', ], ], }, }, Tags: [ { - Key: "test-key", - Value: "test-value", + Key: 'test-key', + Value: 'test-value', }, ], }); }); - test("Basic Creation with a system defined inference profile", () => { - new bedrock.ApplicationInferenceProfile(stack, "TestAIPSystem", { - inferenceProfileName: "TestAIPSystem", + test('Basic Creation with a system defined inference profile', () => { + new bedrock.ApplicationInferenceProfile(stack, 'TestAIPSystem', { + inferenceProfileName: 'TestAIPSystem', modelSource: bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_3_5_SONNET_V2_0, }); - Template.fromStack(stack).hasResourceProperties("AWS::Bedrock::ApplicationInferenceProfile", { - InferenceProfileName: "TestAIPSystem", + Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::ApplicationInferenceProfile', { + InferenceProfileName: 'TestAIPSystem', Description: Match.absent(), ModelSource: { - CopyFrom: "arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0", + CopyFrom: 'arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0', }, }); }); - test("Basic Creation", () => { - new bedrock.ApplicationInferenceProfile(stack, "TestAIPSystem", { - inferenceProfileName: "TestAIPSystem", - modelSource: new bedrock.CrossRegionInferenceProfile(stack, "CrossRegion", { + test('Basic Creation', () => { + new bedrock.ApplicationInferenceProfile(stack, 'TestAIPSystem', { + inferenceProfileName: 'TestAIPSystem', + modelSource: bedrock.CrossRegionInferenceProfile.fromConfig({ model: bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_3_5_SONNET_V2_0, geoRegion: bedrock.CrossRegionInferenceProfileRegion.EU, }), - tags: [{ key: "project", value: "test" }], + tags: [{ key: 'project', value: 'test' }], }); - Template.fromStack(stack).hasResourceProperties("AWS::Bedrock::ApplicationInferenceProfile", { - InferenceProfileName: "TestAIPSystem", + Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::ApplicationInferenceProfile', { + InferenceProfileName: 'TestAIPSystem', Description: Match.absent(), ModelSource: { - CopyFrom: "arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0", + CopyFrom: 'arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0', }, }); }); }); -describe("Imported-ApplicationInferenceProfile", () => { +describe('Imported-ApplicationInferenceProfile', () => { let stack: cdk.Stack; beforeEach(() => { const app = new cdk.App(); cdk.Aspects.of(app).add(new AwsSolutionsChecks()); - stack = new cdk.Stack(app, "TestStack2", { + stack = new cdk.Stack(app, 'TestStack2', { env: { - account: "123456789012", - region: "us-east-1", + account: '123456789012', + region: 'us-east-1', }, }); }); - test("Basic Import - from attributes", () => { - const aip = bedrock.ApplicationInferenceProfile.fromApplicationInferenceProfileAttributes(stack, "TestAIP", { - inferenceProfileArn: "arn:aws:bedrock:us-east-1:123456789012:application-inference-profile/cew2pa5r8hog", - inferenceProfileIdentifier: "arn:aws:bedrock:us-east-1:123456789012:application-inference-profile/cew2pa5r8hog", + test('Basic Import - from attributes', () => { + const aip = bedrock.ApplicationInferenceProfile.fromApplicationInferenceProfileAttributes(stack, 'TestAIP', { + inferenceProfileArn: 'arn:aws:bedrock:us-east-1:123456789012:application-inference-profile/cew2pa5r8hog', + inferenceProfileIdentifier: 'arn:aws:bedrock:us-east-1:123456789012:application-inference-profile/cew2pa5r8hog', }); expect(aip.inferenceProfileArn).toBe( - "arn:aws:bedrock:us-east-1:123456789012:application-inference-profile/cew2pa5r8hog" + 'arn:aws:bedrock:us-east-1:123456789012:application-inference-profile/cew2pa5r8hog', ); - expect(aip.inferenceProfileId).toBe("cew2pa5r8hog"); + expect(aip.inferenceProfileId).toBe('cew2pa5r8hog'); }); - test("Basic Import - from cfn", () => { - const cfnapp = new CfnApplicationInferenceProfile(stack, "mytest", { - inferenceProfileName: "mytest", + test('Basic Import - from cfn', () => { + const cfnapp = new CfnApplicationInferenceProfile(stack, 'mytest', { + inferenceProfileName: 'mytest', modelSource: { - copyFrom: "arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0", + copyFrom: 'arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0', }, }); diff --git a/test/cdk-lib/bedrock/prompts.test.ts b/test/cdk-lib/bedrock/prompts.test.ts index c1feeb11..3b55c44f 100644 --- a/test/cdk-lib/bedrock/prompts.test.ts +++ b/test/cdk-lib/bedrock/prompts.test.ts @@ -16,6 +16,7 @@ import { expect as cdkExpect, haveResource, haveResourceLike } from '@aws-cdk/as import * as cdk from 'aws-cdk-lib'; import { aws_bedrock as cdk_bedrock } from 'aws-cdk-lib'; import * as kms from 'aws-cdk-lib/aws-kms'; +import { BedrockFoundationModel, CrossRegionInferenceProfile, CrossRegionInferenceProfileRegion } from '../../../src/cdk-lib/bedrock'; import { Prompt, PromptVariant } from '../../../src/cdk-lib/bedrock/prompts/prompt'; describe('Prompt', () => { @@ -49,13 +50,11 @@ describe('Prompt', () => { }); // -------------------------------------------------------------------------- - test('creates a Prompt with one variant', () => { + test('creates a Prompt with one variant - fromCdkFoundationModelId', () => { // GIVEN const variant1 = PromptVariant.text({ variantName: 'variant1', - model: cdk_bedrock.FoundationModel.fromFoundationModelId( - stack, - 'model1', + model: BedrockFoundationModel.fromCdkFoundationModelId( cdk_bedrock.FoundationModelIdentifier.ANTHROPIC_CLAUDE_3_SONNET_20240229_V1_0, ), promptVariables: ['topic'], @@ -103,6 +102,111 @@ describe('Prompt', () => { ); }); + test('creates a Prompt with one variant - BedrockFoundationModel', () => { + // GIVEN + const variant1 = PromptVariant.text({ + variantName: 'variant1', + model: BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0, + promptVariables: ['topic'], + promptText: 'This is my first text prompt. Please summarize our conversation on {{topic}}.', + inferenceConfiguration: { + temperature: 1.0, + topP: 0.999, + maxTokens: 2000, + }, + }); + + new Prompt(stack, 'prompt1', { + promptName: 'prompt1', + description: 'my prompt', + defaultVariant: variant1, + variants: [variant1], + }); + // WHEN & THEN + + cdkExpect(stack).to( + haveResourceLike('AWS::Bedrock::Prompt', { + Name: 'prompt1', + Description: 'my prompt', + DefaultVariant: 'variant1', + Variants: [ + { + InferenceConfiguration: { + Text: { + MaxTokens: 2000, + Temperature: 1, + TopP: 0.999, + }, + }, + Name: 'variant1', + TemplateConfiguration: { + Text: { + InputVariables: [{ Name: 'topic' }], + Text: 'This is my first text prompt. Please summarize our conversation on {{topic}}.', + }, + }, + TemplateType: 'TEXT', + }, + ], + }), + ); + }); + + test('creates a Prompt with one variant - CRIS', () => { + // GIVEN + const cris = CrossRegionInferenceProfile.fromConfig({ + geoRegion: CrossRegionInferenceProfileRegion.US, + model: BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0, + }); + + const variant1 = PromptVariant.text({ + variantName: 'variant1', + model: cris, + promptVariables: ['topic'], + promptText: 'This is my first text prompt. Please summarize our conversation on {{topic}}.', + inferenceConfiguration: { + temperature: 1.0, + topP: 0.999, + maxTokens: 2000, + }, + }); + + new Prompt(stack, 'prompt1', { + promptName: 'prompt1', + description: 'my prompt', + defaultVariant: variant1, + variants: [variant1], + }); + // WHEN & THEN + + cdkExpect(stack).to( + haveResourceLike('AWS::Bedrock::Prompt', { + Name: 'prompt1', + Description: 'my prompt', + DefaultVariant: 'variant1', + Variants: [ + { + InferenceConfiguration: { + Text: { + MaxTokens: 2000, + Temperature: 1, + TopP: 0.999, + }, + }, + Name: 'variant1', + TemplateConfiguration: { + Text: { + InputVariables: [{ Name: 'topic' }], + Text: 'This is my first text prompt. Please summarize our conversation on {{topic}}.', + }, + }, + TemplateType: 'TEXT', + }, + ], + }), + ); + }); + // -------------------------------------------------------------------------- test('creates a prompt version', () => { // GIVEN @@ -144,9 +248,7 @@ describe('Prompt', () => { const variants = [1, 2, 3, 4].map((id) => PromptVariant.text({ variantName: `variant${id}`, - model: cdk_bedrock.FoundationModel.fromFoundationModelId( - stack, - `model${id}`, + model: BedrockFoundationModel.fromCdkFoundationModelId( cdk_bedrock.FoundationModelIdentifier.ANTHROPIC_CLAUDE_3_SONNET_20240229_V1_0, ), promptVariables: ['topic'], diff --git a/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.assets.json b/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.assets.json index 68b8fe8d..d8718241 100644 --- a/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.assets.json +++ b/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.assets.json @@ -1,7 +1,7 @@ { "version": "38.0.1", "files": { - "03aa0c514f7316feaae4c91b323088e017e0ab4ffca7cce7f8b85bae49db40a0": { + "f8e5222a07f590ff8b8136fe9fad952bae4af560da13748723517ab32056c895": { "source": { "path": "aws-cdk-bedrock-guardrails-integ-test.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-us-west-2": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-us-west-2", - "objectKey": "03aa0c514f7316feaae4c91b323088e017e0ab4ffca7cce7f8b85bae49db40a0.json", + "objectKey": "f8e5222a07f590ff8b8136fe9fad952bae4af560da13748723517ab32056c895.json", "region": "us-west-2", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-us-west-2" } diff --git a/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.template.json b/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.template.json index dec4951b..6dbbb7b7 100644 --- a/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.template.json +++ b/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.template.json @@ -66,15 +66,27 @@ { "Ref": "AWS::Partition" }, - ":bedrock:", + ":bedrock:*::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0" + ] + ] + } + }, + { + "Action": "bedrock:InvokeModel", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", { - "Ref": "AWS::Region" + "Ref": "AWS::Partition" }, - ":", + ":bedrock:", { - "Ref": "AWS::AccountId" + "Ref": "AWS::Region" }, - ":foundation-model/anthropic.claude-3-sonnet-20240229-v1:0" + "::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0" ] ] } diff --git a/test/integ/inference-profiles.integ.ts b/test/integ/inference-profiles.integ.ts index 80b6b9e4..5e6a8e95 100644 --- a/test/integ/inference-profiles.integ.ts +++ b/test/integ/inference-profiles.integ.ts @@ -10,50 +10,43 @@ * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions * and limitations under the License. */ -import * as integ from "@aws-cdk/integ-tests-alpha"; -import * as cdk from "aws-cdk-lib"; +import * as integ from '@aws-cdk/integ-tests-alpha'; +import * as cdk from 'aws-cdk-lib'; import { Agent, ApplicationInferenceProfile, BedrockFoundationModel, CrossRegionInferenceProfile, CrossRegionInferenceProfileRegion, -} from "../../src/cdk-lib/bedrock"; +} from '../../src/cdk-lib/bedrock'; const app = new cdk.App(); -const stack = new cdk.Stack(app, "aws-cdk-bedrock-guardrails-integ-test", { +const stack = new cdk.Stack(app, 'aws-cdk-bedrock-guardrails-integ-test', { env: { - region: "us-west-2", + region: 'us-west-2', }, }); -new Agent(stack, "TestAgent", { - instruction: "You are a test bot that needs to be very gentle and useful to the user", - model: CrossRegionInferenceProfile.fromConfig({ +new Agent(stack, 'TestAgent', { + instruction: 'You are a test bot that needs to be very gentle and useful to the user', + foundationModel: CrossRegionInferenceProfile.fromConfig({ geoRegion: CrossRegionInferenceProfileRegion.US, model: BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0, }), - name: "test-agent", - description: "test-description", + name: 'test-agent', + description: 'test-description', }); -const myProjectApi = new ApplicationInferenceProfile(stack, "TestAppProfile", { - inferenceProfileName: "my-app-inf-profile", - tags: [{ key: "projectId", value: "supplyUSXRC28" }], +new ApplicationInferenceProfile(stack, 'TestAppProfile', { + inferenceProfileName: 'my-app-inf-profile', + tags: [{ key: 'projectId', value: 'supplyUSXRC28' }], modelSource: CrossRegionInferenceProfile.fromConfig({ geoRegion: CrossRegionInferenceProfileRegion.US, model: BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0, }), }); -// new Agent(stack, "TestAgent-23", { -// instruction: "You are a new test bot that needs to be very gentle and useful to the user", -// model: myProjectApi, -// name: "test-agent-23", -// description: "test-description", -// }); - -new integ.IntegTest(app, "ServiceTest", { +new integ.IntegTest(app, 'ServiceTest', { testCases: [stack], cdkCommandOptions: { destroy: { From 674ab79885dec5c3ad23a1c529dd8a64bd03bb46 Mon Sep 17 00:00:00 2001 From: krokoko Date: Tue, 19 Nov 2024 19:53:08 -0600 Subject: [PATCH 18/22] chore(tests): fix tests --- CHANGELOG.md | 4 +- src/cdk-lib/bedrock/README.md | 54 +++++-- test/cdk-lib/bedrock/agent.test.ts | 133 +++++++++++++++++- .../cdk-lib/bedrock/inference-profile.test.ts | 78 +++++++++- test/cdk-lib/bedrock/models.test.ts | 51 ++++++- 5 files changed, 290 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a36dff0..ed629d71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ -# CDK Generative AI Constructs V0.1.282 (2024-11-18) +# CDK Generative AI Constructs V0.1.283 (2024-11-20) -Based on CDK library version 2.166.0.0 +Based on CDK library version 2.166.0 # CDK Generative AI Constructs V0.1.273 (2024-10-15) diff --git a/src/cdk-lib/bedrock/README.md b/src/cdk-lib/bedrock/README.md index 92b03dc1..7fdc3c65 100644 --- a/src/cdk-lib/bedrock/README.md +++ b/src/cdk-lib/bedrock/README.md @@ -407,7 +407,7 @@ kb.addS3DataSource({ bucket, chunkingStrategy: ChunkingStrategy.SEMANTIC, parsingStrategy: ParsingStategy.foundationModel({ - model: BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0.asIModel(stack), + model: BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0, }), }); @@ -728,7 +728,7 @@ two parsing strategies: ```ts bedrock.ParsingStategy.foundationModel({ - model: BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0.asIModel(stack), + model: BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0, }); ``` @@ -736,7 +736,7 @@ two parsing strategies: ```python bedrock.ParsingStategy.foundation_model( - parsing_model=BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0.as_i_model(self) + parsing_model=BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0 ) ``` @@ -1219,7 +1219,7 @@ Example of `Prompt`: ```ts const cmk = new kms.Key(this, "cmk", {}); -const claudeModel = BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0.asIModel(this); +const claudeModel = BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0; const variant1 = PromptVariant.text({ variantName: "variant1", @@ -1296,6 +1296,30 @@ or alternatively: prompt1.createVersion("my first version"); ``` +## System defined inference profiles + +You can build a CrossRegionInferenceProfile using a system defined inference profile. The inference profile will route requests to the Regions defined in the cross region (system-defined) inference profile that you choose. You can find the system defined inference profiles by navigating to your console (Amazon Bedrock -> Cross-region inference) or programmatically, for instance using [boto3](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/bedrock/client/list_inference_profiles.html). + +Before using creating a CrossRegionInferenceProfile, ensure that you have access to the models and regions defined in the inference profiles. For instance, if you see the system defined inference profile "us.anthropic.claude-3-5-sonnet-20241022-v2:0" defined in your region, the table mentions that inference requests will be routed to US East (Virginia) us-east-1, US East (Ohio) us-east-2 and US West (Oregon) us-west-2. Thus, you need to have model access enabled in those regions for the model ```anthropic.claude-3-5-sonnet-20241022-v2:0```. You can then create the CrossRegionInferenceProfile as follows: + +TypeScript + +```ts +const cris = bedrock.CrossRegionInferenceProfile.fromConfig({ + geoRegion: bedrock.CrossRegionInferenceProfileRegion.US, + model: bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_3_5_SONNET_V2_0 +}); +``` + +Python + +```python +cris = bedrock.CrossRegionInferenceProfile.from_config( + geo_region= bedrock.CrossRegionInferenceProfileRegion.US, + model= bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_3_5_SONNET_V2_0 +) +``` + ## Application inference profile You can create an application inference profile with one or more Regions to track usage and costs when invoking a model. @@ -1336,14 +1360,19 @@ TypeScript // You can use the 'bedrock.BedrockFoundationModel' or pass the arn as a string const appInfProfile1 = new ApplicationInferenceProfile(this, 'myapplicationprofile', { inferenceProfileName: 'claude 3 sonnet v1', - modelSource: bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0.asArn(stack), + modelSource: bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0, tags: [{key: 'test', value: 'test'}] }); -// To create an application inference profile across regions, specify the cross region inference profile's ARN +// To create an application inference profile across regions, specify the cross region inference profile +const cris = bedrock.CrossRegionInferenceProfile.fromConfig({ + geoRegion: bedrock.CrossRegionInferenceProfileRegion.US, + model: bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_3_5_SONNET_V2_0 +}); + const appInfProfile2 = new ApplicationInferenceProfile(this, 'myapplicationprofile2', { inferenceProfileName: 'claude 3 sonnet v1', - modelSource: 'arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0' + modelSource: cris }); // Import a Cfn L1 construct created application inference profile @@ -1372,17 +1401,22 @@ Python # You can use the 'bedrock.BedrockFoundationModel' or pass the arn as a string appInfProfile1 = bedrock.ApplicationInferenceProfile(self, 'myapplicationprofile', inference_profile_name='claude 3 sonnet v1', - model_source=bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0.asArn(stack), + model_source=bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0, tags=[CfnTag( key="key", value="value" )] ) -# To create an application inference profile across regions, specify the cross region inference profile's ARN +# To create an application inference profile across regions, specify the cross region inference profile +cris = bedrock.CrossRegionInferenceProfile.from_config( + geo_region= bedrock.CrossRegionInferenceProfileRegion.US, + model= bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_3_5_SONNET_V2_0 +) + appInfProfile2 = bedrock.ApplicationInferenceProfile(self, 'myapplicationprofile2', inference_profile_name='claude 35 sonnet v2', - model_source='arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0' + model_source=cris ) # Import an inference profile through attributes diff --git a/test/cdk-lib/bedrock/agent.test.ts b/test/cdk-lib/bedrock/agent.test.ts index 6bde743c..fe967422 100644 --- a/test/cdk-lib/bedrock/agent.test.ts +++ b/test/cdk-lib/bedrock/agent.test.ts @@ -16,7 +16,7 @@ import { Annotations, Match, Template } from 'aws-cdk-lib/assertions'; import { Key } from 'aws-cdk-lib/aws-kms'; import * as lambda from 'aws-cdk-lib/aws-lambda'; import * as s3 from 'aws-cdk-lib/aws-s3'; -import { NagSuppressions } from 'cdk-nag'; +import { NagSuppressions, AwsSolutionsChecks } from 'cdk-nag'; import * as bedrock from '../../../src/cdk-lib/bedrock'; import * as foundationModels from '../../../src/cdk-lib/bedrock/models'; @@ -158,7 +158,18 @@ describe('Agent with guardrails through addGuardrail', () => { KnowledgeBaseConfiguration: { Type: 'VECTOR', VectorKnowledgeBaseConfiguration: { - EmbeddingModelArn: 'arn:aws:bedrock:us-east-1::foundation-model/amazon.titan-embed-text-v1', + EmbeddingModelArn: { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':bedrock:', + { Ref: 'AWS::Region' }, + '::foundation-model/amazon.titan-embed-text-v1', + ], + ], + }, }, }, }); @@ -183,7 +194,18 @@ describe('Agent with guardrails through addGuardrail', () => { test('Agent is created', () => { Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::Agent', { - FoundationModel: 'anthropic.claude-v2:1', + FoundationModel: { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':bedrock:', + { Ref: 'AWS::Region' }, + '::foundation-model/anthropic.claude-v2:1', + ], + ], + }, Instruction: 'You provide support for developers working with CDK constructs.', IdleSessionTTLInSeconds: 1800, PromptOverrideConfiguration: { @@ -417,7 +439,18 @@ describe('Agent with guardrails through constructor', () => { KnowledgeBaseConfiguration: { Type: 'VECTOR', VectorKnowledgeBaseConfiguration: { - EmbeddingModelArn: 'arn:aws:bedrock:us-east-1::foundation-model/amazon.titan-embed-text-v1', + EmbeddingModelArn: { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':bedrock:', + { Ref: 'AWS::Region' }, + '::foundation-model/amazon.titan-embed-text-v1', + ], + ], + }, }, }, }); @@ -442,7 +475,18 @@ describe('Agent with guardrails through constructor', () => { test('Agent is created', () => { Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::Agent', { - FoundationModel: 'anthropic.claude-v2:1', + FoundationModel: { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':bedrock:', + { Ref: 'AWS::Region' }, + '::foundation-model/anthropic.claude-v2:1', + ], + ], + }, Instruction: 'You provide support for developers working with CDK constructs.', IdleSessionTTLInSeconds: 1800, PromptOverrideConfiguration: { @@ -655,7 +699,22 @@ describe('Agent without guardrails', () => { KnowledgeBaseConfiguration: { Type: 'VECTOR', VectorKnowledgeBaseConfiguration: { - EmbeddingModelArn: 'arn:aws:bedrock:us-east-1::foundation-model/amazon.titan-embed-text-v1', + EmbeddingModelArn: { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':bedrock:', + { + Ref: 'AWS::Region', + }, + '::foundation-model/amazon.titan-embed-text-v1', + ], + ], + }, }, }, }); @@ -680,7 +739,18 @@ describe('Agent without guardrails', () => { test('Agent is created', () => { Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::Agent', { - FoundationModel: 'anthropic.claude-v2:1', + FoundationModel: { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':bedrock:', + { Ref: 'AWS::Region' }, + '::foundation-model/anthropic.claude-v2:1', + ], + ], + }, Instruction: 'You provide support for developers working with CDK constructs.', IdleSessionTTLInSeconds: 1800, PromptOverrideConfiguration: { @@ -806,3 +876,52 @@ describe('Imports', () => { expect(agentAlias.aliasArn).toEqual('arn:aws:bedrock:us-east-1:123456789012:agent-alias/DNCJJYQKSU/TCLCITFZTN'); }); }); + +describe('Agent with CRIS', () => { + let app: cdk.App; + let stack: cdk.Stack; + + beforeEach(() => { + app = new cdk.App(); + cdk.Aspects.of(app).add(new AwsSolutionsChecks()); + stack = new cdk.Stack(app, 'TestStack'); + + const cris = bedrock.CrossRegionInferenceProfile.fromConfig({ + geoRegion: bedrock.CrossRegionInferenceProfileRegion.US, + model: bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_3_5_HAIKU_V1_0, + }); + + new bedrock.Agent(stack, 'Agent', { + foundationModel: cris, + instruction: 'You provide support for developers working with CDK constructs.', + enableUserInput: true, + }); + }); + + test('Foundation model', () => { + // GIVEN + Template.fromStack(stack).hasResourceProperties('AWS::Bedrock::Agent', { + FoundationModel: { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':bedrock:', + { + Ref: 'AWS::Region', + }, + ':', + { + Ref: 'AWS::AccountId', + }, + ':inference-profile/us.anthropic.claude-3-5-haiku-20241022-v1:0', + ], + ], + }, + Instruction: 'You provide support for developers working with CDK constructs.', + }); + }); +}); diff --git a/test/cdk-lib/bedrock/inference-profile.test.ts b/test/cdk-lib/bedrock/inference-profile.test.ts index 3583657b..00880546 100644 --- a/test/cdk-lib/bedrock/inference-profile.test.ts +++ b/test/cdk-lib/bedrock/inference-profile.test.ts @@ -25,14 +25,14 @@ describe('CDK-Created-Cross-Region-Inference-Profile', () => { stack = new cdk.Stack(app, 'TestStack'); }); - test('Basic Creation', () => { + /*test('Basic Creation', () => { const cris = bedrock.CrossRegionInferenceProfile.fromConfig({ geoRegion: bedrock.CrossRegionInferenceProfileRegion.EU, model: bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0, }); expect(cris.inferenceProfileArn).toBe('cew2pa5r8hog'); - }); + });*/ test('Basic Creation with a system defined inference profile', () => { new bedrock.ApplicationInferenceProfile(stack, 'TestAIPSystem', { @@ -44,7 +44,18 @@ describe('CDK-Created-Cross-Region-Inference-Profile', () => { InferenceProfileName: 'TestAIPSystem', Description: Match.absent(), ModelSource: { - CopyFrom: 'arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0', + CopyFrom: { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':bedrock:', + { Ref: 'AWS::Region' }, + '::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0', + ], + ], + }, }, }); }); @@ -63,7 +74,26 @@ describe('CDK-Created-Cross-Region-Inference-Profile', () => { InferenceProfileName: 'TestAIPSystem', Description: Match.absent(), ModelSource: { - CopyFrom: 'arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0', + CopyFrom: { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':bedrock:', + { + Ref: 'AWS::Region', + }, + ':', + { + Ref: 'AWS::AccountId', + }, + ':inference-profile/eu.anthropic.claude-3-5-sonnet-20241022-v2:0', + ], + ], + }, }, }); }); @@ -94,7 +124,11 @@ describe('CDK-Created-Application-Inference-Profile', () => { 'Fn::Join': [ '', [ - 'arn:aws:bedrock:', + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':bedrock:', { Ref: 'AWS::Region', }, @@ -122,7 +156,18 @@ describe('CDK-Created-Application-Inference-Profile', () => { InferenceProfileName: 'TestAIPSystem', Description: Match.absent(), ModelSource: { - CopyFrom: 'arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0', + CopyFrom: { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':bedrock:', + { Ref: 'AWS::Region' }, + '::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0', + ], + ], + }, }, }); }); @@ -141,7 +186,26 @@ describe('CDK-Created-Application-Inference-Profile', () => { InferenceProfileName: 'TestAIPSystem', Description: Match.absent(), ModelSource: { - CopyFrom: 'arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0', + CopyFrom: { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':bedrock:', + { + Ref: 'AWS::Region', + }, + ':', + { + Ref: 'AWS::AccountId', + }, + ':inference-profile/eu.anthropic.claude-3-5-sonnet-20241022-v2:0', + ], + ], + }, }, }); }); diff --git a/test/cdk-lib/bedrock/models.test.ts b/test/cdk-lib/bedrock/models.test.ts index eda508af..9286ffe1 100644 --- a/test/cdk-lib/bedrock/models.test.ts +++ b/test/cdk-lib/bedrock/models.test.ts @@ -22,7 +22,7 @@ describe('BedrockFoundationModel', () => { .toBe('amazon.titan-embed-text-v1'); }); - test('returns ARN', () => { + test('returns ARN from BedrockFoundationModel', () => { const app = new cdk.App(); cdk.Aspects.of(app).add(new AwsSolutionsChecks()); const stack = new cdk.Stack(app, 'test-stack', { @@ -31,9 +31,52 @@ describe('BedrockFoundationModel', () => { region: 'us-east-1', }, }); - const construct = new Construct(stack, 'test-construct'); - expect(BedrockFoundationModel.TITAN_EMBED_TEXT_V1.asArn(construct)) - .toBe('arn:aws:bedrock:us-east-1::foundation-model/amazon.titan-embed-text-v1'); + new Construct(stack, 'test-construct'); + + expect(BedrockFoundationModel.TITAN_EMBED_TEXT_V1.invokableArn).toMatch( + /^arn:\${Token\[AWS\.Partition\.\d+\]}:bedrock:\${Token\[AWS\.Region\.\d+\]}::foundation-model\/amazon\.titan-embed-text-v1$/, + ); + + }); + + test('returns ARN fromCdkFoundationModelId', () => { + const app = new cdk.App(); + cdk.Aspects.of(app).add(new AwsSolutionsChecks()); + const stack = new cdk.Stack(app, 'test-stack', { + env: { + account: '123456789012', + region: 'us-east-1', + }, + }); + new Construct(stack, 'test-construct'); + + expect(BedrockFoundationModel.fromCdkFoundationModelId( + cdk.aws_bedrock.FoundationModelIdentifier.ANTHROPIC_CLAUDE_3_5_SONNET_20241022_V2_0, + ).invokableArn).toMatch( + /^arn:\${Token\[AWS\.Partition\.\d+\]}:bedrock:\${Token\[AWS\.Region\.\d+\]}::foundation-model\/anthropic\.claude-3-5-sonnet-20241022-v2:0$/, + ); + + }); + + test('returns ARN fromCdkFoundationModel', () => { + const app = new cdk.App(); + cdk.Aspects.of(app).add(new AwsSolutionsChecks()); + const stack = new cdk.Stack(app, 'test-stack', { + env: { + account: '123456789012', + region: 'us-east-1', + }, + }); + new Construct(stack, 'test-construct'); + + expect(BedrockFoundationModel.fromCdkFoundationModelId( + cdk.aws_bedrock.FoundationModel.fromFoundationModelId( + stack, + 'mymodel', + cdk.aws_bedrock.FoundationModelIdentifier.ANTHROPIC_CLAUDE_3_5_SONNET_20241022_V2_0, + )).invokableArn).toMatch( + /^arn:\${Token\[AWS\.Partition\.\d+\]}:bedrock:\${Token\[AWS\.Region\.\d+\]}::foundation-model\/anthropic\.claude-3-5-sonnet-20241022-v2:0$/, + ); }); }); From b9958ea12bdfd35750a64def61f492cd84d2fdd0 Mon Sep 17 00:00:00 2001 From: Rafael Mosca Date: Wed, 20 Nov 2024 17:07:02 +0100 Subject: [PATCH 19/22] docs(bedrock): updated docstrings --- .../application-inference-profile.ts | 35 ++++++------ .../cross-region-inference-profile.ts | 57 ++++++++++++------- 2 files changed, 55 insertions(+), 37 deletions(-) diff --git a/src/cdk-lib/bedrock/inference-profiles/application-inference-profile.ts b/src/cdk-lib/bedrock/inference-profiles/application-inference-profile.ts index 46eb148a..38e6a1f6 100644 --- a/src/cdk-lib/bedrock/inference-profiles/application-inference-profile.ts +++ b/src/cdk-lib/bedrock/inference-profiles/application-inference-profile.ts @@ -10,12 +10,12 @@ * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions * and limitations under the License. */ -import { CfnTag, Arn, ArnFormat } from 'aws-cdk-lib'; -import * as bedrock from 'aws-cdk-lib/aws-bedrock'; -import { Grant, IGrantable } from 'aws-cdk-lib/aws-iam'; -import { Construct } from 'constructs'; -import { IInferenceProfile, InferenceProfileBase, InferenceProfileType } from './common'; -import { IInvokable } from '../models'; +import { CfnTag, Arn, ArnFormat } from "aws-cdk-lib"; +import * as bedrock from "aws-cdk-lib/aws-bedrock"; +import { Grant, IGrantable } from "aws-cdk-lib/aws-iam"; +import { Construct } from "constructs"; +import { IInferenceProfile, InferenceProfileBase, InferenceProfileType } from "./common"; +import { IInvokable } from "../models"; /****************************************************************************** * PROPS FOR NEW CONSTRUCT @@ -82,7 +82,7 @@ export class ApplicationInferenceProfile extends InferenceProfileBase implements public static fromApplicationInferenceProfileAttributes( scope: Construct, id: string, - attrs: ApplicationInferenceProfileAttributes, + attrs: ApplicationInferenceProfileAttributes ): IInferenceProfile { class Import extends InferenceProfileBase { public readonly inferenceProfileArn = attrs.inferenceProfileArn; @@ -97,32 +97,32 @@ export class ApplicationInferenceProfile extends InferenceProfileBase implements * Import a low-level L1 Cfn ApplicationInferenceProfile */ public static fromCfnApplicationInferenceProfile( - CfnApplicationInferenceProfile: bedrock.CfnApplicationInferenceProfile, + CfnApplicationInferenceProfile: bedrock.CfnApplicationInferenceProfile ): IInferenceProfile { return new (class extends InferenceProfileBase { public readonly inferenceProfileArn = CfnApplicationInferenceProfile.attrInferenceProfileArn; public readonly inferenceProfileId = CfnApplicationInferenceProfile.attrInferenceProfileId; public readonly type = InferenceProfileType.APPLICATION; - })(CfnApplicationInferenceProfile, '@FromCfnApplicationInferenceProfile'); + })(CfnApplicationInferenceProfile, "@FromCfnApplicationInferenceProfile"); } /** * The name of the application inference profile. */ public readonly inferenceProfileName: string; /** - * The ARN of the application inference profile. + * The ARN of the application application inference profile. */ public readonly inferenceProfileArn: string; /** - * The unique identifier of the inference profile. + * The unique identifier of the application inference profile. */ public readonly inferenceProfileId: string; /** - * The unique identifier of the inference profile. + * The underlying model/cross-region model used by the application inference profile. */ public readonly inferenceProfileModel: IInvokable; /** - * The status of the inference profile. ACTIVE means that the inference profile is ready to be used. + * The status of the application inference profile. ACTIVE means that the inference profile is ready to be used. */ public readonly status: string; /** @@ -184,7 +184,6 @@ export class ApplicationInferenceProfile extends InferenceProfileBase implements * Gives the appropriate policies to invoke and use the Foundation Model. */ public grantInvoke(grantee: IGrantable): Grant { - // for CRIS, we need to provide permissions to invoke // the model in all regions where the inference profile // can route requests. Since we manipulate a inferenceProfileModel @@ -196,8 +195,8 @@ export class ApplicationInferenceProfile extends InferenceProfileBase implements const invokableArn = Arn.format({ partition: splitted.partition, service: splitted.service, - region: '*', - account: '', + region: "*", + account: "", resource: splitted.resource, resourceName: splitted.resourceName, arnFormat: ArnFormat.SLASH_RESOURCE_NAME, @@ -205,7 +204,7 @@ export class ApplicationInferenceProfile extends InferenceProfileBase implements Grant.addToPrincipal({ grantee: grantee, - actions: ['bedrock:InvokeModel'], + actions: ["bedrock:InvokeModel"], resourceArns: [invokableArn], }); @@ -219,7 +218,7 @@ export class ApplicationInferenceProfile extends InferenceProfileBase implements grantProfileUsage(grantee: IGrantable): Grant { const grant = Grant.addToPrincipal({ grantee: grantee, - actions: ['bedrock:GetInferenceProfile', 'bedrock:InvokeModel'], + actions: ["bedrock:GetInferenceProfile", "bedrock:InvokeModel"], resourceArns: [this.inferenceProfileArn], }); return grant; diff --git a/src/cdk-lib/bedrock/inference-profiles/cross-region-inference-profile.ts b/src/cdk-lib/bedrock/inference-profiles/cross-region-inference-profile.ts index 52776475..d9da0da4 100644 --- a/src/cdk-lib/bedrock/inference-profiles/cross-region-inference-profile.ts +++ b/src/cdk-lib/bedrock/inference-profiles/cross-region-inference-profile.ts @@ -10,24 +10,38 @@ * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions * and limitations under the License. */ -import { Arn, ArnFormat, Aws } from 'aws-cdk-lib'; -import { Grant, IGrantable } from 'aws-cdk-lib/aws-iam'; -import { BedrockFoundationModel, IInvokable } from '../models'; -import { IInferenceProfile, InferenceProfileType } from './common'; +import { Arn, ArnFormat, Aws } from "aws-cdk-lib"; +import { Grant, IGrantable } from "aws-cdk-lib/aws-iam"; +import { BedrockFoundationModel, IInvokable } from "../models"; +import { IInferenceProfile, InferenceProfileType } from "./common"; export enum CrossRegionInferenceProfileRegion { /** - * EU: Frankfurt (eu-central-1), Ireland (eu-west-1), Paris (eu-west-3) + * Cross-region Inference Identifier for the European area. + * According to the model chosen, this might include: + * - Frankfurt (`eu-central-1`) + * - Ireland (`eu-west-1`) + * - Paris (`eu-west-3`) */ - EU = 'eu', + EU = "eu", /** - * US: N. Virginia (us-east-1), Oregon (us-west-2) + * Cross-region Inference Identifier for the United States area. + * According to the model chosen, this might include: + * - N. Virginia (`us-east-1`) + * - Oregon (`us-west-2`) + * - Ohio (`us-east-2`) */ - US = 'us', + US = "us", /** - * This might include: ap-northeast-1, ap-northeast-2, ap-south-1, ap-southeast-1, and ap-southeast-2 + * Cross-region Inference Identifier for the Asia-Pacific area. + * According to the model chosen, this might include: + * - Tokyo (`ap-northeast-1`) + * - Seoul (`ap-northeast-2`) + * - Mumbai (`ap-south-1`) + * - Singapore (`ap-southeast-1`) + * - Sydney (`ap-southeast-2`) */ - APAC = 'apac', + APAC = "apac", } /****************************************************************************** @@ -68,7 +82,13 @@ export class CrossRegionInferenceProfile implements IInvokable, IInferenceProfil * @example 'arn:aws:bedrock:us-east-1:123456789012:inference-profile/us.anthropic.claude-3-5-sonnet-20240620-v1:0' */ public readonly inferenceProfileArn: string; + /** + * @example InferenceProfileType.SYSTEM_DEFINED + */ public readonly type: InferenceProfileType; + /** + * The underlying model supporting cross-region inference. + */ public readonly inferenceProfileModel: BedrockFoundationModel; /** This equals to the inferenceProfileArn property, useful just to implement IInvokable interface*/ public readonly invokableArn: string; @@ -82,10 +102,10 @@ export class CrossRegionInferenceProfile implements IInvokable, IInferenceProfil this.inferenceProfileId = `${props.geoRegion}.${props.model.modelId}`; this.inferenceProfileArn = Arn.format({ partition: Aws.PARTITION, - service: 'bedrock', + service: "bedrock", account: Aws.ACCOUNT_ID, region: Aws.REGION, - resource: 'inference-profile', + resource: "inference-profile", resourceName: this.inferenceProfileId, arnFormat: ArnFormat.SLASH_RESOURCE_NAME, }); @@ -97,23 +117,22 @@ export class CrossRegionInferenceProfile implements IInvokable, IInferenceProfil * Gives the appropriate policies to invoke and use the Foundation Model. */ public grantInvoke(grantee: IGrantable): Grant { - // for CRIS, we need to provide permissions to invoke // the model in all regions where the inference profile // can route requests const invokableArn = Arn.format({ partition: Aws.PARTITION, - service: 'bedrock', - region: '*', - account: '', - resource: 'foundation-model', + service: "bedrock", + region: "*", + account: "", + resource: "foundation-model", resourceName: this.inferenceProfileModel.modelId, arnFormat: ArnFormat.SLASH_RESOURCE_NAME, }); Grant.addToPrincipal({ grantee: grantee, - actions: ['bedrock:InvokeModel'], + actions: ["bedrock:InvokeModel"], resourceArns: [invokableArn], }); @@ -128,7 +147,7 @@ export class CrossRegionInferenceProfile implements IInvokable, IInferenceProfil grantProfileUsage(grantee: IGrantable): Grant { const grant = Grant.addToPrincipal({ grantee: grantee, - actions: ['bedrock:GetInferenceProfile', 'bedrock:InvokeModel'], + actions: ["bedrock:GetInferenceProfile", "bedrock:InvokeModel"], resourceArns: [this.inferenceProfileArn], }); return grant; From 2323e3c9a92a7f84d1e82dab862065ce2e5fd1ef Mon Sep 17 00:00:00 2001 From: Rafael Mosca Date: Wed, 20 Nov 2024 18:15:44 +0100 Subject: [PATCH 20/22] fix(bedrock): update grant-invoke --- .../application-inference-profile.ts | 32 ++---- .../cross-region-inference-profile.ts | 24 +--- src/cdk-lib/bedrock/models.ts | 103 +++++++++++------- test/integ/inference-profiles.integ.ts | 42 ++++--- 4 files changed, 103 insertions(+), 98 deletions(-) diff --git a/src/cdk-lib/bedrock/inference-profiles/application-inference-profile.ts b/src/cdk-lib/bedrock/inference-profiles/application-inference-profile.ts index 38e6a1f6..b887fa4f 100644 --- a/src/cdk-lib/bedrock/inference-profiles/application-inference-profile.ts +++ b/src/cdk-lib/bedrock/inference-profiles/application-inference-profile.ts @@ -181,39 +181,21 @@ export class ApplicationInferenceProfile extends InferenceProfileBase implements } /** - * Gives the appropriate policies to invoke and use the Foundation Model. + * Gives the appropriate policies to invoke and use the application inference profile. */ public grantInvoke(grantee: IGrantable): Grant { - // for CRIS, we need to provide permissions to invoke - // the model in all regions where the inference profile - // can route requests. Since we manipulate a inferenceProfileModel - // which is a IInvokable, we don't have the model Id available. - // To get this information back, we split the existing Arn, and update - // the regions - const splitted = Arn.split(this.inferenceProfileModel.invokableArn, ArnFormat.SLASH_RESOURCE_NAME); + // This method ensures the appropriate permissions are given + // to use either the inference profile or the vanilla FM + this.inferenceProfileModel.grantInvoke(grantee); - const invokableArn = Arn.format({ - partition: splitted.partition, - service: splitted.service, - region: "*", - account: "", - resource: splitted.resource, - resourceName: splitted.resourceName, - arnFormat: ArnFormat.SLASH_RESOURCE_NAME, - }); - - Grant.addToPrincipal({ - grantee: grantee, - actions: ["bedrock:InvokeModel"], - resourceArns: [invokableArn], - }); + // plus we add permissions to now invoke the application inference profile itself. return this.grantProfileUsage(grantee); } /** - * Grants appropriate permissions to use the cross-region inference profile. - * Does not grant permissions to use the model in the profile. + * Grants appropriate permissions to use the application inference profile (AIP). + * Does not grant permissions to use the model/cross-region profile in the AIP. */ grantProfileUsage(grantee: IGrantable): Grant { const grant = Grant.addToPrincipal({ diff --git a/src/cdk-lib/bedrock/inference-profiles/cross-region-inference-profile.ts b/src/cdk-lib/bedrock/inference-profiles/cross-region-inference-profile.ts index d9da0da4..c1fcc921 100644 --- a/src/cdk-lib/bedrock/inference-profiles/cross-region-inference-profile.ts +++ b/src/cdk-lib/bedrock/inference-profiles/cross-region-inference-profile.ts @@ -117,26 +117,10 @@ export class CrossRegionInferenceProfile implements IInvokable, IInferenceProfil * Gives the appropriate policies to invoke and use the Foundation Model. */ public grantInvoke(grantee: IGrantable): Grant { - // for CRIS, we need to provide permissions to invoke - // the model in all regions where the inference profile - // can route requests - const invokableArn = Arn.format({ - partition: Aws.PARTITION, - service: "bedrock", - region: "*", - account: "", - resource: "foundation-model", - resourceName: this.inferenceProfileModel.modelId, - arnFormat: ArnFormat.SLASH_RESOURCE_NAME, - }); - - Grant.addToPrincipal({ - grantee: grantee, - actions: ["bedrock:InvokeModel"], - resourceArns: [invokableArn], - }); - - this.inferenceProfileModel.grantInvoke(grantee); + // for CRIS, we need to provide permissions to invoke the model in all regions + // where the inference profile can route requests + this.inferenceProfileModel.grantInvokeAllRegions(grantee); + // and we need to provide permissions to invoke the inference profile itself return this.grantProfileUsage(grantee); } diff --git a/src/cdk-lib/bedrock/models.ts b/src/cdk-lib/bedrock/models.ts index c48dd035..ce9822c8 100644 --- a/src/cdk-lib/bedrock/models.ts +++ b/src/cdk-lib/bedrock/models.ts @@ -11,10 +11,10 @@ * and limitations under the License. */ -import { Arn, ArnFormat, Aws } from 'aws-cdk-lib'; -import { IModel, FoundationModel, FoundationModelIdentifier } from 'aws-cdk-lib/aws-bedrock'; -import { Grant, IGrantable } from 'aws-cdk-lib/aws-iam'; -import { IConstruct } from 'constructs'; +import { Arn, ArnFormat, Aws } from "aws-cdk-lib"; +import { IModel, FoundationModel, FoundationModelIdentifier } from "aws-cdk-lib/aws-bedrock"; +import { Grant, IGrantable } from "aws-cdk-lib/aws-iam"; +import { IConstruct } from "constructs"; /** * Represents an Amazon Bedrock abstraction on which you can @@ -68,30 +68,30 @@ export class BedrockFoundationModel implements IInvokable { /**************************************************************************** * AMAZON ***************************************************************************/ - public static readonly AMAZON_TITAN_TEXT_EXPRESS_V1 = new BedrockFoundationModel('amazon.titan-text-express-v1', { + public static readonly AMAZON_TITAN_TEXT_EXPRESS_V1 = new BedrockFoundationModel("amazon.titan-text-express-v1", { supportsAgents: true, }); - public static readonly AMAZON_TITAN_PREMIER_V1_0 = new BedrockFoundationModel('amazon.titan-text-premier-v1:0', { + public static readonly AMAZON_TITAN_PREMIER_V1_0 = new BedrockFoundationModel("amazon.titan-text-premier-v1:0", { supportsAgents: true, }); - public static readonly TITAN_EMBED_TEXT_V1 = new BedrockFoundationModel('amazon.titan-embed-text-v1', { + public static readonly TITAN_EMBED_TEXT_V1 = new BedrockFoundationModel("amazon.titan-embed-text-v1", { supportsKnowledgeBase: true, vectorDimensions: 1536, }); - public static readonly TITAN_EMBED_TEXT_V2_1024 = new BedrockFoundationModel('amazon.titan-embed-text-v2:0', { + public static readonly TITAN_EMBED_TEXT_V2_1024 = new BedrockFoundationModel("amazon.titan-embed-text-v2:0", { supportsKnowledgeBase: true, vectorDimensions: 1024, }); - public static readonly TITAN_EMBED_TEXT_V2_512 = new BedrockFoundationModel('amazon.titan-embed-text-v2:0', { + public static readonly TITAN_EMBED_TEXT_V2_512 = new BedrockFoundationModel("amazon.titan-embed-text-v2:0", { supportsKnowledgeBase: true, vectorDimensions: 512, }); - public static readonly TITAN_EMBED_TEXT_V2_256 = new BedrockFoundationModel('amazon.titan-embed-text-v2:0', { + public static readonly TITAN_EMBED_TEXT_V2_256 = new BedrockFoundationModel("amazon.titan-embed-text-v2:0", { supportsKnowledgeBase: true, vectorDimensions: 256, }); @@ -99,56 +99,56 @@ export class BedrockFoundationModel implements IInvokable { * ANTHROPIC ***************************************************************************/ public static readonly ANTHROPIC_CLAUDE_3_5_SONNET_V2_0 = new BedrockFoundationModel( - 'anthropic.claude-3-5-sonnet-20241022-v2:0', - { supportsAgents: true, supportsCrossRegion: true }, + "anthropic.claude-3-5-sonnet-20241022-v2:0", + { supportsAgents: true, supportsCrossRegion: true } ); public static readonly ANTHROPIC_CLAUDE_3_5_SONNET_V1_0 = new BedrockFoundationModel( - 'anthropic.claude-3-5-sonnet-20240620-v1:0', - { supportsAgents: true, supportsCrossRegion: true }, + "anthropic.claude-3-5-sonnet-20240620-v1:0", + { supportsAgents: true, supportsCrossRegion: true } ); public static readonly ANTHROPIC_CLAUDE_3_5_HAIKU_V1_0 = new BedrockFoundationModel( - 'anthropic.claude-3-5-haiku-20241022-v1:0', - { supportsAgents: true, supportsCrossRegion: true }, + "anthropic.claude-3-5-haiku-20241022-v1:0", + { supportsAgents: true, supportsCrossRegion: true } ); public static readonly ANTHROPIC_CLAUDE_OPUS_V1_0 = new BedrockFoundationModel( - 'anthropic.claude-3-opus-20240229-v1:0', - { supportsAgents: true }, + "anthropic.claude-3-opus-20240229-v1:0", + { supportsAgents: true } ); public static readonly ANTHROPIC_CLAUDE_SONNET_V1_0 = new BedrockFoundationModel( - 'anthropic.claude-3-sonnet-20240229-v1:0', - { supportsAgents: true, supportsCrossRegion: true }, + "anthropic.claude-3-sonnet-20240229-v1:0", + { supportsAgents: true, supportsCrossRegion: true } ); public static readonly ANTHROPIC_CLAUDE_HAIKU_V1_0 = new BedrockFoundationModel( - 'anthropic.claude-3-haiku-20240307-v1:0', - { supportsAgents: true, supportsCrossRegion: true }, + "anthropic.claude-3-haiku-20240307-v1:0", + { supportsAgents: true, supportsCrossRegion: true } ); - public static readonly ANTHROPIC_CLAUDE_V2_1 = new BedrockFoundationModel('anthropic.claude-v2:1', { + public static readonly ANTHROPIC_CLAUDE_V2_1 = new BedrockFoundationModel("anthropic.claude-v2:1", { supportsAgents: true, }); - public static readonly ANTHROPIC_CLAUDE_V2 = new BedrockFoundationModel('anthropic.claude-v2', { + public static readonly ANTHROPIC_CLAUDE_V2 = new BedrockFoundationModel("anthropic.claude-v2", { supportsAgents: true, }); - public static readonly ANTHROPIC_CLAUDE_INSTANT_V1_2 = new BedrockFoundationModel('anthropic.claude-instant-v1', { + public static readonly ANTHROPIC_CLAUDE_INSTANT_V1_2 = new BedrockFoundationModel("anthropic.claude-instant-v1", { supportsAgents: true, }); /**************************************************************************** * COHERE ***************************************************************************/ - public static readonly COHERE_EMBED_ENGLISH_V3 = new BedrockFoundationModel('cohere.embed-english-v3', { + public static readonly COHERE_EMBED_ENGLISH_V3 = new BedrockFoundationModel("cohere.embed-english-v3", { supportsKnowledgeBase: true, vectorDimensions: 1024, }); - public static readonly COHERE_EMBED_MULTILINGUAL_V3 = new BedrockFoundationModel('cohere.embed-multilingual-v3', { + public static readonly COHERE_EMBED_MULTILINGUAL_V3 = new BedrockFoundationModel("cohere.embed-multilingual-v3", { supportsKnowledgeBase: true, vectorDimensions: 1024, }); @@ -157,24 +157,30 @@ export class BedrockFoundationModel implements IInvokable { * META ***************************************************************************/ public static readonly META_LLAMA_3_2_11B_INSTRUCT_V1 = new BedrockFoundationModel( - 'meta.llama3-2-11b-instruct-v1:0', + "meta.llama3-2-11b-instruct-v1:0", { supportsCrossRegion: true, - }, + } ); - public static readonly META_LLAMA_3_2_3B_INSTRUCT_V1 = new BedrockFoundationModel('meta.llama3-2-3b-instruct-v1:0', { + public static readonly META_LLAMA_3_2_3B_INSTRUCT_V1 = new BedrockFoundationModel("meta.llama3-2-3b-instruct-v1:0", { supportsCrossRegion: true, }); - public static readonly META_LLAMA_3_2_1B_INSTRUCT_V1 = new BedrockFoundationModel('meta.llama3-2-1b-instruct-v1:0', { + public static readonly META_LLAMA_3_2_1B_INSTRUCT_V1 = new BedrockFoundationModel("meta.llama3-2-1b-instruct-v1:0", { supportsCrossRegion: true, }); - public static fromCdkFoundationModelId(modelId: FoundationModelIdentifier, props: BedrockFoundationModelProps = {}): BedrockFoundationModel { + public static fromCdkFoundationModelId( + modelId: FoundationModelIdentifier, + props: BedrockFoundationModelProps = {} + ): BedrockFoundationModel { return new BedrockFoundationModel(modelId.modelId, props); } - public static fromCdkFoundationModel(modelId: FoundationModel, props: BedrockFoundationModelProps = {}): BedrockFoundationModel { + public static fromCdkFoundationModel( + modelId: FoundationModel, + props: BedrockFoundationModelProps = {} + ): BedrockFoundationModel { return new BedrockFoundationModel(modelId.modelId, props); } @@ -192,10 +198,10 @@ export class BedrockFoundationModel implements IInvokable { this.modelId = value; this.modelArn = Arn.format({ partition: Aws.PARTITION, - service: 'bedrock', + service: "bedrock", region: Aws.REGION, - account: '', - resource: 'foundation-model', + account: "", + resource: "foundation-model", resourceName: this.modelId, arnFormat: ArnFormat.SLASH_RESOURCE_NAME, }); @@ -227,14 +233,35 @@ export class BedrockFoundationModel implements IInvokable { } /** - * Gives the appropriate policies to invoke and use the Foundation Model. + * Gives the appropriate policies to invoke and use the Foundation Model in the stack region. */ public grantInvoke(grantee: IGrantable): Grant { const grant = Grant.addToPrincipal({ grantee: grantee, - actions: ['bedrock:InvokeModel'], + actions: ["bedrock:InvokeModel"], resourceArns: [this.invokableArn], }); return grant; } + + /** + * Gives the appropriate policies to invoke and use the Foundation Model in all regions. + */ + public grantInvokeAllRegions(grantee: IGrantable): Grant { + const invokableArn = Arn.format({ + partition: Aws.PARTITION, + service: "bedrock", + region: "*", + account: "", + resource: "foundation-model", + resourceName: this.modelId, + arnFormat: ArnFormat.SLASH_RESOURCE_NAME, + }); + + return Grant.addToPrincipal({ + grantee: grantee, + actions: ["bedrock:InvokeModel"], + resourceArns: [invokableArn], + }); + } } diff --git a/test/integ/inference-profiles.integ.ts b/test/integ/inference-profiles.integ.ts index 5e6a8e95..607afac4 100644 --- a/test/integ/inference-profiles.integ.ts +++ b/test/integ/inference-profiles.integ.ts @@ -10,43 +10,55 @@ * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions * and limitations under the License. */ -import * as integ from '@aws-cdk/integ-tests-alpha'; -import * as cdk from 'aws-cdk-lib'; +import * as integ from "@aws-cdk/integ-tests-alpha"; +import * as cdk from "aws-cdk-lib"; import { Agent, ApplicationInferenceProfile, BedrockFoundationModel, CrossRegionInferenceProfile, CrossRegionInferenceProfileRegion, -} from '../../src/cdk-lib/bedrock'; +} from "../../src/cdk-lib/bedrock"; const app = new cdk.App(); -const stack = new cdk.Stack(app, 'aws-cdk-bedrock-guardrails-integ-test', { +const stack = new cdk.Stack(app, "aws-cdk-bedrock-guardrails-integ-test", { env: { - region: 'us-west-2', + region: "eu-central-1", }, }); +new Agent(stack, "TestAgent-simple", { + instruction: "You are a test bot that needs to be very gentle and useful to the user", + foundationModel: BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0, + name: "test-agent-simple", + description: "test-description", +}); -new Agent(stack, 'TestAgent', { - instruction: 'You are a test bot that needs to be very gentle and useful to the user', +new Agent(stack, "TestAgent-cris", { + instruction: "You are a test bot that needs to be very gentle and useful to the user", foundationModel: CrossRegionInferenceProfile.fromConfig({ - geoRegion: CrossRegionInferenceProfileRegion.US, + geoRegion: CrossRegionInferenceProfileRegion.EU, model: BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0, }), - name: 'test-agent', - description: 'test-description', + name: "test-agent-cris", + description: "test-description", }); -new ApplicationInferenceProfile(stack, 'TestAppProfile', { - inferenceProfileName: 'my-app-inf-profile', - tags: [{ key: 'projectId', value: 'supplyUSXRC28' }], +const aip = new ApplicationInferenceProfile(stack, "TestAppProfile", { + inferenceProfileName: "my-app-inf-profile", + tags: [{ key: "projectId", value: "supplyUSXRC28" }], modelSource: CrossRegionInferenceProfile.fromConfig({ - geoRegion: CrossRegionInferenceProfileRegion.US, + geoRegion: CrossRegionInferenceProfileRegion.EU, model: BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0, }), }); -new integ.IntegTest(app, 'ServiceTest', { +new Agent(stack, "TestAgent-aip", { + instruction: "You are a test bot that needs to be very gentle and useful to the user", + foundationModel: aip, + name: "test-agent-aip", + description: "test-description", +}); +new integ.IntegTest(app, "ServiceTest", { testCases: [stack], cdkCommandOptions: { destroy: { From 350f0ce430d75af04acd386f1c253f3c1cd87b70 Mon Sep 17 00:00:00 2001 From: krokoko Date: Wed, 20 Nov 2024 11:30:08 -0600 Subject: [PATCH 21/22] chore(build): fix build --- .../classes/ApplicationInferenceProfile.md | 14 +- .../bedrock/classes/BedrockFoundationModel.md | 18 +- .../classes/CrossRegionInferenceProfile.md | 8 +- .../CrossRegionInferenceProfileRegion.md | 20 +- .../application-inference-profile.ts | 20 +- .../cross-region-inference-profile.ts | 20 +- src/cdk-lib/bedrock/models.ts | 84 ++--- ...-bedrock-guardrails-integ-test.assets.json | 12 +- ...edrock-guardrails-integ-test.template.json | 290 ++++++++++++++++-- test/integ/inference-profiles.integ.ts | 42 +-- 10 files changed, 409 insertions(+), 119 deletions(-) diff --git a/apidocs/namespaces/bedrock/classes/ApplicationInferenceProfile.md b/apidocs/namespaces/bedrock/classes/ApplicationInferenceProfile.md index 674a034b..9fb34b4f 100644 --- a/apidocs/namespaces/bedrock/classes/ApplicationInferenceProfile.md +++ b/apidocs/namespaces/bedrock/classes/ApplicationInferenceProfile.md @@ -80,7 +80,7 @@ that might be different than the stack they were imported into. > `readonly` **inferenceProfileArn**: `string` -The ARN of the application inference profile. +The ARN of the application application inference profile. #### Overrides @@ -92,7 +92,7 @@ The ARN of the application inference profile. > `readonly` **inferenceProfileId**: `string` -The unique identifier of the inference profile. +The unique identifier of the application inference profile. #### Overrides @@ -104,7 +104,7 @@ The unique identifier of the inference profile. > `readonly` **inferenceProfileModel**: [`IInvokable`](../interfaces/IInvokable.md) -The unique identifier of the inference profile. +The underlying model/cross-region model used by the application inference profile. *** @@ -175,7 +175,7 @@ The stack in which this resource is defined. > `readonly` **status**: `string` -The status of the inference profile. ACTIVE means that the inference profile is ready to be used. +The status of the application inference profile. ACTIVE means that the inference profile is ready to be used. *** @@ -335,7 +335,7 @@ Commonly this is the resource's `ref`. > **grantInvoke**(`grantee`): `Grant` -Gives the appropriate policies to invoke and use the Foundation Model. +Gives the appropriate policies to invoke and use the application inference profile. #### Parameters @@ -355,8 +355,8 @@ Gives the appropriate policies to invoke and use the Foundation Model. > **grantProfileUsage**(`grantee`): `Grant` -Grants appropriate permissions to use the cross-region inference profile. -Does not grant permissions to use the model in the profile. +Grants appropriate permissions to use the application inference profile (AIP). +Does not grant permissions to use the model/cross-region profile in the AIP. #### Parameters diff --git a/apidocs/namespaces/bedrock/classes/BedrockFoundationModel.md b/apidocs/namespaces/bedrock/classes/BedrockFoundationModel.md index 0637d10c..f272f044 100644 --- a/apidocs/namespaces/bedrock/classes/BedrockFoundationModel.md +++ b/apidocs/namespaces/bedrock/classes/BedrockFoundationModel.md @@ -256,7 +256,7 @@ Returns the ARN of the foundation model in the following format: > **grantInvoke**(`grantee`): `Grant` -Gives the appropriate policies to invoke and use the Foundation Model. +Gives the appropriate policies to invoke and use the Foundation Model in the stack region. #### Parameters @@ -272,6 +272,22 @@ Gives the appropriate policies to invoke and use the Foundation Model. *** +### grantInvokeAllRegions() + +> **grantInvokeAllRegions**(`grantee`): `Grant` + +Gives the appropriate policies to invoke and use the Foundation Model in all regions. + +#### Parameters + +• **grantee**: `IGrantable` + +#### Returns + +`Grant` + +*** + ### toString() > **toString**(): `string` diff --git a/apidocs/namespaces/bedrock/classes/CrossRegionInferenceProfile.md b/apidocs/namespaces/bedrock/classes/CrossRegionInferenceProfile.md index 60c6f76d..b798ee90 100644 --- a/apidocs/namespaces/bedrock/classes/CrossRegionInferenceProfile.md +++ b/apidocs/namespaces/bedrock/classes/CrossRegionInferenceProfile.md @@ -58,6 +58,8 @@ https://docs.aws.amazon.com/bedrock/latest/userguide/cross-region-inference.html > `readonly` **inferenceProfileModel**: [`BedrockFoundationModel`](BedrockFoundationModel.md) +The underlying model supporting cross-region inference. + *** ### invokableArn @@ -76,7 +78,11 @@ This equals to the inferenceProfileArn property, useful just to implement IInvok > `readonly` **type**: [`InferenceProfileType`](../enumerations/InferenceProfileType.md) -The type of inference profile. +#### Example + +```ts +InferenceProfileType.SYSTEM_DEFINED +``` #### Implementation of diff --git a/apidocs/namespaces/bedrock/enumerations/CrossRegionInferenceProfileRegion.md b/apidocs/namespaces/bedrock/enumerations/CrossRegionInferenceProfileRegion.md index 37cafeac..e3cc6225 100644 --- a/apidocs/namespaces/bedrock/enumerations/CrossRegionInferenceProfileRegion.md +++ b/apidocs/namespaces/bedrock/enumerations/CrossRegionInferenceProfileRegion.md @@ -12,7 +12,13 @@ > **APAC**: `"apac"` -This might include: ap-northeast-1, ap-northeast-2, ap-south-1, ap-southeast-1, and ap-southeast-2 +Cross-region Inference Identifier for the Asia-Pacific area. +According to the model chosen, this might include: +- Tokyo (`ap-northeast-1`) +- Seoul (`ap-northeast-2`) +- Mumbai (`ap-south-1`) +- Singapore (`ap-southeast-1`) +- Sydney (`ap-southeast-2`) *** @@ -20,7 +26,11 @@ This might include: ap-northeast-1, ap-northeast-2, ap-south-1, ap-southeast-1, > **EU**: `"eu"` -EU: Frankfurt (eu-central-1), Ireland (eu-west-1), Paris (eu-west-3) +Cross-region Inference Identifier for the European area. +According to the model chosen, this might include: +- Frankfurt (`eu-central-1`) +- Ireland (`eu-west-1`) +- Paris (`eu-west-3`) *** @@ -28,4 +38,8 @@ EU: Frankfurt (eu-central-1), Ireland (eu-west-1), Paris (eu-west-3) > **US**: `"us"` -US: N. Virginia (us-east-1), Oregon (us-west-2) +Cross-region Inference Identifier for the United States area. +According to the model chosen, this might include: +- N. Virginia (`us-east-1`) +- Oregon (`us-west-2`) +- Ohio (`us-east-2`) diff --git a/src/cdk-lib/bedrock/inference-profiles/application-inference-profile.ts b/src/cdk-lib/bedrock/inference-profiles/application-inference-profile.ts index b887fa4f..0cdc1d16 100644 --- a/src/cdk-lib/bedrock/inference-profiles/application-inference-profile.ts +++ b/src/cdk-lib/bedrock/inference-profiles/application-inference-profile.ts @@ -10,12 +10,12 @@ * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions * and limitations under the License. */ -import { CfnTag, Arn, ArnFormat } from "aws-cdk-lib"; -import * as bedrock from "aws-cdk-lib/aws-bedrock"; -import { Grant, IGrantable } from "aws-cdk-lib/aws-iam"; -import { Construct } from "constructs"; -import { IInferenceProfile, InferenceProfileBase, InferenceProfileType } from "./common"; -import { IInvokable } from "../models"; +import { CfnTag, Arn, ArnFormat } from 'aws-cdk-lib'; +import * as bedrock from 'aws-cdk-lib/aws-bedrock'; +import { Grant, IGrantable } from 'aws-cdk-lib/aws-iam'; +import { Construct } from 'constructs'; +import { IInferenceProfile, InferenceProfileBase, InferenceProfileType } from './common'; +import { IInvokable } from '../models'; /****************************************************************************** * PROPS FOR NEW CONSTRUCT @@ -82,7 +82,7 @@ export class ApplicationInferenceProfile extends InferenceProfileBase implements public static fromApplicationInferenceProfileAttributes( scope: Construct, id: string, - attrs: ApplicationInferenceProfileAttributes + attrs: ApplicationInferenceProfileAttributes, ): IInferenceProfile { class Import extends InferenceProfileBase { public readonly inferenceProfileArn = attrs.inferenceProfileArn; @@ -97,13 +97,13 @@ export class ApplicationInferenceProfile extends InferenceProfileBase implements * Import a low-level L1 Cfn ApplicationInferenceProfile */ public static fromCfnApplicationInferenceProfile( - CfnApplicationInferenceProfile: bedrock.CfnApplicationInferenceProfile + CfnApplicationInferenceProfile: bedrock.CfnApplicationInferenceProfile, ): IInferenceProfile { return new (class extends InferenceProfileBase { public readonly inferenceProfileArn = CfnApplicationInferenceProfile.attrInferenceProfileArn; public readonly inferenceProfileId = CfnApplicationInferenceProfile.attrInferenceProfileId; public readonly type = InferenceProfileType.APPLICATION; - })(CfnApplicationInferenceProfile, "@FromCfnApplicationInferenceProfile"); + })(CfnApplicationInferenceProfile, '@FromCfnApplicationInferenceProfile'); } /** * The name of the application inference profile. @@ -200,7 +200,7 @@ export class ApplicationInferenceProfile extends InferenceProfileBase implements grantProfileUsage(grantee: IGrantable): Grant { const grant = Grant.addToPrincipal({ grantee: grantee, - actions: ["bedrock:GetInferenceProfile", "bedrock:InvokeModel"], + actions: ['bedrock:GetInferenceProfile', 'bedrock:InvokeModel'], resourceArns: [this.inferenceProfileArn], }); return grant; diff --git a/src/cdk-lib/bedrock/inference-profiles/cross-region-inference-profile.ts b/src/cdk-lib/bedrock/inference-profiles/cross-region-inference-profile.ts index c1fcc921..598d82a3 100644 --- a/src/cdk-lib/bedrock/inference-profiles/cross-region-inference-profile.ts +++ b/src/cdk-lib/bedrock/inference-profiles/cross-region-inference-profile.ts @@ -10,10 +10,10 @@ * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions * and limitations under the License. */ -import { Arn, ArnFormat, Aws } from "aws-cdk-lib"; -import { Grant, IGrantable } from "aws-cdk-lib/aws-iam"; -import { BedrockFoundationModel, IInvokable } from "../models"; -import { IInferenceProfile, InferenceProfileType } from "./common"; +import { Arn, ArnFormat, Aws } from 'aws-cdk-lib'; +import { Grant, IGrantable } from 'aws-cdk-lib/aws-iam'; +import { BedrockFoundationModel, IInvokable } from '../models'; +import { IInferenceProfile, InferenceProfileType } from './common'; export enum CrossRegionInferenceProfileRegion { /** @@ -23,7 +23,7 @@ export enum CrossRegionInferenceProfileRegion { * - Ireland (`eu-west-1`) * - Paris (`eu-west-3`) */ - EU = "eu", + EU = 'eu', /** * Cross-region Inference Identifier for the United States area. * According to the model chosen, this might include: @@ -31,7 +31,7 @@ export enum CrossRegionInferenceProfileRegion { * - Oregon (`us-west-2`) * - Ohio (`us-east-2`) */ - US = "us", + US = 'us', /** * Cross-region Inference Identifier for the Asia-Pacific area. * According to the model chosen, this might include: @@ -41,7 +41,7 @@ export enum CrossRegionInferenceProfileRegion { * - Singapore (`ap-southeast-1`) * - Sydney (`ap-southeast-2`) */ - APAC = "apac", + APAC = 'apac', } /****************************************************************************** @@ -102,10 +102,10 @@ export class CrossRegionInferenceProfile implements IInvokable, IInferenceProfil this.inferenceProfileId = `${props.geoRegion}.${props.model.modelId}`; this.inferenceProfileArn = Arn.format({ partition: Aws.PARTITION, - service: "bedrock", + service: 'bedrock', account: Aws.ACCOUNT_ID, region: Aws.REGION, - resource: "inference-profile", + resource: 'inference-profile', resourceName: this.inferenceProfileId, arnFormat: ArnFormat.SLASH_RESOURCE_NAME, }); @@ -131,7 +131,7 @@ export class CrossRegionInferenceProfile implements IInvokable, IInferenceProfil grantProfileUsage(grantee: IGrantable): Grant { const grant = Grant.addToPrincipal({ grantee: grantee, - actions: ["bedrock:GetInferenceProfile", "bedrock:InvokeModel"], + actions: ['bedrock:GetInferenceProfile', 'bedrock:InvokeModel'], resourceArns: [this.inferenceProfileArn], }); return grant; diff --git a/src/cdk-lib/bedrock/models.ts b/src/cdk-lib/bedrock/models.ts index ce9822c8..09a3db2c 100644 --- a/src/cdk-lib/bedrock/models.ts +++ b/src/cdk-lib/bedrock/models.ts @@ -11,10 +11,10 @@ * and limitations under the License. */ -import { Arn, ArnFormat, Aws } from "aws-cdk-lib"; -import { IModel, FoundationModel, FoundationModelIdentifier } from "aws-cdk-lib/aws-bedrock"; -import { Grant, IGrantable } from "aws-cdk-lib/aws-iam"; -import { IConstruct } from "constructs"; +import { Arn, ArnFormat, Aws } from 'aws-cdk-lib'; +import { IModel, FoundationModel, FoundationModelIdentifier } from 'aws-cdk-lib/aws-bedrock'; +import { Grant, IGrantable } from 'aws-cdk-lib/aws-iam'; +import { IConstruct } from 'constructs'; /** * Represents an Amazon Bedrock abstraction on which you can @@ -68,30 +68,30 @@ export class BedrockFoundationModel implements IInvokable { /**************************************************************************** * AMAZON ***************************************************************************/ - public static readonly AMAZON_TITAN_TEXT_EXPRESS_V1 = new BedrockFoundationModel("amazon.titan-text-express-v1", { + public static readonly AMAZON_TITAN_TEXT_EXPRESS_V1 = new BedrockFoundationModel('amazon.titan-text-express-v1', { supportsAgents: true, }); - public static readonly AMAZON_TITAN_PREMIER_V1_0 = new BedrockFoundationModel("amazon.titan-text-premier-v1:0", { + public static readonly AMAZON_TITAN_PREMIER_V1_0 = new BedrockFoundationModel('amazon.titan-text-premier-v1:0', { supportsAgents: true, }); - public static readonly TITAN_EMBED_TEXT_V1 = new BedrockFoundationModel("amazon.titan-embed-text-v1", { + public static readonly TITAN_EMBED_TEXT_V1 = new BedrockFoundationModel('amazon.titan-embed-text-v1', { supportsKnowledgeBase: true, vectorDimensions: 1536, }); - public static readonly TITAN_EMBED_TEXT_V2_1024 = new BedrockFoundationModel("amazon.titan-embed-text-v2:0", { + public static readonly TITAN_EMBED_TEXT_V2_1024 = new BedrockFoundationModel('amazon.titan-embed-text-v2:0', { supportsKnowledgeBase: true, vectorDimensions: 1024, }); - public static readonly TITAN_EMBED_TEXT_V2_512 = new BedrockFoundationModel("amazon.titan-embed-text-v2:0", { + public static readonly TITAN_EMBED_TEXT_V2_512 = new BedrockFoundationModel('amazon.titan-embed-text-v2:0', { supportsKnowledgeBase: true, vectorDimensions: 512, }); - public static readonly TITAN_EMBED_TEXT_V2_256 = new BedrockFoundationModel("amazon.titan-embed-text-v2:0", { + public static readonly TITAN_EMBED_TEXT_V2_256 = new BedrockFoundationModel('amazon.titan-embed-text-v2:0', { supportsKnowledgeBase: true, vectorDimensions: 256, }); @@ -99,56 +99,56 @@ export class BedrockFoundationModel implements IInvokable { * ANTHROPIC ***************************************************************************/ public static readonly ANTHROPIC_CLAUDE_3_5_SONNET_V2_0 = new BedrockFoundationModel( - "anthropic.claude-3-5-sonnet-20241022-v2:0", - { supportsAgents: true, supportsCrossRegion: true } + 'anthropic.claude-3-5-sonnet-20241022-v2:0', + { supportsAgents: true, supportsCrossRegion: true }, ); public static readonly ANTHROPIC_CLAUDE_3_5_SONNET_V1_0 = new BedrockFoundationModel( - "anthropic.claude-3-5-sonnet-20240620-v1:0", - { supportsAgents: true, supportsCrossRegion: true } + 'anthropic.claude-3-5-sonnet-20240620-v1:0', + { supportsAgents: true, supportsCrossRegion: true }, ); public static readonly ANTHROPIC_CLAUDE_3_5_HAIKU_V1_0 = new BedrockFoundationModel( - "anthropic.claude-3-5-haiku-20241022-v1:0", - { supportsAgents: true, supportsCrossRegion: true } + 'anthropic.claude-3-5-haiku-20241022-v1:0', + { supportsAgents: true, supportsCrossRegion: true }, ); public static readonly ANTHROPIC_CLAUDE_OPUS_V1_0 = new BedrockFoundationModel( - "anthropic.claude-3-opus-20240229-v1:0", - { supportsAgents: true } + 'anthropic.claude-3-opus-20240229-v1:0', + { supportsAgents: true }, ); public static readonly ANTHROPIC_CLAUDE_SONNET_V1_0 = new BedrockFoundationModel( - "anthropic.claude-3-sonnet-20240229-v1:0", - { supportsAgents: true, supportsCrossRegion: true } + 'anthropic.claude-3-sonnet-20240229-v1:0', + { supportsAgents: true, supportsCrossRegion: true }, ); public static readonly ANTHROPIC_CLAUDE_HAIKU_V1_0 = new BedrockFoundationModel( - "anthropic.claude-3-haiku-20240307-v1:0", - { supportsAgents: true, supportsCrossRegion: true } + 'anthropic.claude-3-haiku-20240307-v1:0', + { supportsAgents: true, supportsCrossRegion: true }, ); - public static readonly ANTHROPIC_CLAUDE_V2_1 = new BedrockFoundationModel("anthropic.claude-v2:1", { + public static readonly ANTHROPIC_CLAUDE_V2_1 = new BedrockFoundationModel('anthropic.claude-v2:1', { supportsAgents: true, }); - public static readonly ANTHROPIC_CLAUDE_V2 = new BedrockFoundationModel("anthropic.claude-v2", { + public static readonly ANTHROPIC_CLAUDE_V2 = new BedrockFoundationModel('anthropic.claude-v2', { supportsAgents: true, }); - public static readonly ANTHROPIC_CLAUDE_INSTANT_V1_2 = new BedrockFoundationModel("anthropic.claude-instant-v1", { + public static readonly ANTHROPIC_CLAUDE_INSTANT_V1_2 = new BedrockFoundationModel('anthropic.claude-instant-v1', { supportsAgents: true, }); /**************************************************************************** * COHERE ***************************************************************************/ - public static readonly COHERE_EMBED_ENGLISH_V3 = new BedrockFoundationModel("cohere.embed-english-v3", { + public static readonly COHERE_EMBED_ENGLISH_V3 = new BedrockFoundationModel('cohere.embed-english-v3', { supportsKnowledgeBase: true, vectorDimensions: 1024, }); - public static readonly COHERE_EMBED_MULTILINGUAL_V3 = new BedrockFoundationModel("cohere.embed-multilingual-v3", { + public static readonly COHERE_EMBED_MULTILINGUAL_V3 = new BedrockFoundationModel('cohere.embed-multilingual-v3', { supportsKnowledgeBase: true, vectorDimensions: 1024, }); @@ -157,29 +157,29 @@ export class BedrockFoundationModel implements IInvokable { * META ***************************************************************************/ public static readonly META_LLAMA_3_2_11B_INSTRUCT_V1 = new BedrockFoundationModel( - "meta.llama3-2-11b-instruct-v1:0", + 'meta.llama3-2-11b-instruct-v1:0', { supportsCrossRegion: true, - } + }, ); - public static readonly META_LLAMA_3_2_3B_INSTRUCT_V1 = new BedrockFoundationModel("meta.llama3-2-3b-instruct-v1:0", { + public static readonly META_LLAMA_3_2_3B_INSTRUCT_V1 = new BedrockFoundationModel('meta.llama3-2-3b-instruct-v1:0', { supportsCrossRegion: true, }); - public static readonly META_LLAMA_3_2_1B_INSTRUCT_V1 = new BedrockFoundationModel("meta.llama3-2-1b-instruct-v1:0", { + public static readonly META_LLAMA_3_2_1B_INSTRUCT_V1 = new BedrockFoundationModel('meta.llama3-2-1b-instruct-v1:0', { supportsCrossRegion: true, }); public static fromCdkFoundationModelId( modelId: FoundationModelIdentifier, - props: BedrockFoundationModelProps = {} + props: BedrockFoundationModelProps = {}, ): BedrockFoundationModel { return new BedrockFoundationModel(modelId.modelId, props); } public static fromCdkFoundationModel( modelId: FoundationModel, - props: BedrockFoundationModelProps = {} + props: BedrockFoundationModelProps = {}, ): BedrockFoundationModel { return new BedrockFoundationModel(modelId.modelId, props); } @@ -198,10 +198,10 @@ export class BedrockFoundationModel implements IInvokable { this.modelId = value; this.modelArn = Arn.format({ partition: Aws.PARTITION, - service: "bedrock", + service: 'bedrock', region: Aws.REGION, - account: "", - resource: "foundation-model", + account: '', + resource: 'foundation-model', resourceName: this.modelId, arnFormat: ArnFormat.SLASH_RESOURCE_NAME, }); @@ -238,7 +238,7 @@ export class BedrockFoundationModel implements IInvokable { public grantInvoke(grantee: IGrantable): Grant { const grant = Grant.addToPrincipal({ grantee: grantee, - actions: ["bedrock:InvokeModel"], + actions: ['bedrock:InvokeModel'], resourceArns: [this.invokableArn], }); return grant; @@ -250,17 +250,17 @@ export class BedrockFoundationModel implements IInvokable { public grantInvokeAllRegions(grantee: IGrantable): Grant { const invokableArn = Arn.format({ partition: Aws.PARTITION, - service: "bedrock", - region: "*", - account: "", - resource: "foundation-model", + service: 'bedrock', + region: '*', + account: '', + resource: 'foundation-model', resourceName: this.modelId, arnFormat: ArnFormat.SLASH_RESOURCE_NAME, }); return Grant.addToPrincipal({ grantee: grantee, - actions: ["bedrock:InvokeModel"], + actions: ['bedrock:InvokeModel'], resourceArns: [invokableArn], }); } diff --git a/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.assets.json b/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.assets.json index d8718241..d9732249 100644 --- a/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.assets.json +++ b/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.assets.json @@ -1,17 +1,17 @@ { "version": "38.0.1", "files": { - "f8e5222a07f590ff8b8136fe9fad952bae4af560da13748723517ab32056c895": { + "91dac6b16ba4df2701f08f5f6d386e6409d930f45d5e0c62fdcaad8a37cc69b0": { "source": { "path": "aws-cdk-bedrock-guardrails-integ-test.template.json", "packaging": "file" }, "destinations": { - "current_account-us-west-2": { - "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-us-west-2", - "objectKey": "f8e5222a07f590ff8b8136fe9fad952bae4af560da13748723517ab32056c895.json", - "region": "us-west-2", - "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-us-west-2" + "current_account-eu-central-1": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-eu-central-1", + "objectKey": "91dac6b16ba4df2701f08f5f6d386e6409d930f45d5e0c62fdcaad8a37cc69b0.json", + "region": "eu-central-1", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-eu-central-1" } } } diff --git a/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.template.json b/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.template.json index 6dbbb7b7..018bab7e 100644 --- a/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.template.json +++ b/test/integ/inference-profiles.integ.snapshot/aws-cdk-bedrock-guardrails-integ-test.template.json @@ -1,6 +1,6 @@ { "Resources": { - "TestAgentRole522C6259": { + "TestAgentsimpleRole3DF8CB4B": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { @@ -29,7 +29,7 @@ { "Ref": "AWS::Partition" }, - ":bedrock:us-west-2:", + ":bedrock:eu-central-1:", { "Ref": "AWS::AccountId" }, @@ -47,10 +47,10 @@ ], "Version": "2012-10-17" }, - "RoleName": "AmazonBedrockExecutionRoleForAgents_awscdkbedrtTestAgent6A742A85" + "RoleName": "AmazonBedrockExecutionRoleForAgents_awscdkbedrgentsimpleCE146514" } }, - "TestAgentRoleDefaultPolicy0A38CDBA": { + "TestAgentsimpleRoleDefaultPolicy585202B2": { "Type": "AWS::IAM::Policy", "Properties": { "PolicyDocument": { @@ -66,11 +66,119 @@ { "Ref": "AWS::Partition" }, - ":bedrock:*::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0" + ":bedrock:", + { + "Ref": "AWS::Region" + }, + "::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0" ] ] } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "TestAgentsimpleRoleDefaultPolicy585202B2", + "Roles": [ + { + "Ref": "TestAgentsimpleRole3DF8CB4B" + } + ] + } + }, + "TestAgentsimpleAgentAACF0DC1": { + "Type": "AWS::Bedrock::Agent", + "Properties": { + "ActionGroups": [ + { + "ActionGroupName": "UserInputAction", + "ActionGroupState": "DISABLED", + "ParentActionGroupSignature": "AMAZON.UserInput", + "SkipResourceInUseCheckOnDelete": false + } + ], + "AgentName": "test-agent-simple", + "AgentResourceRoleArn": { + "Fn::GetAtt": [ + "TestAgentsimpleRole3DF8CB4B", + "Arn" + ] + }, + "Description": "test-description", + "FoundationModel": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":bedrock:", + { + "Ref": "AWS::Region" + }, + "::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0" + ] + ] + }, + "Instruction": "You are a test bot that needs to be very gentle and useful to the user" + } + }, + "TestAgentcrisRole15797E3B": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "bedrock.amazonaws.com" + } }, + { + "Action": "sts:AssumeRole", + "Condition": { + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + }, + "ArnLike": { + "aws:SourceArn": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":bedrock:eu-central-1:", + { + "Ref": "AWS::AccountId" + }, + ":agent/*" + ] + ] + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "bedrock.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "RoleName": "AmazonBedrockExecutionRoleForAgents_awscdkbedrtAgentcrisF7C16C4F" + } + }, + "TestAgentcrisRoleDefaultPolicy6C083E13": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ { "Action": "bedrock:InvokeModel", "Effect": "Allow", @@ -82,11 +190,7 @@ { "Ref": "AWS::Partition" }, - ":bedrock:", - { - "Ref": "AWS::Region" - }, - "::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0" + ":bedrock:*::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0" ] ] } @@ -113,7 +217,7 @@ { "Ref": "AWS::AccountId" }, - ":inference-profile/us.anthropic.claude-3-sonnet-20240229-v1:0" + ":inference-profile/eu.anthropic.claude-3-sonnet-20240229-v1:0" ] ] } @@ -121,15 +225,15 @@ ], "Version": "2012-10-17" }, - "PolicyName": "TestAgentRoleDefaultPolicy0A38CDBA", + "PolicyName": "TestAgentcrisRoleDefaultPolicy6C083E13", "Roles": [ { - "Ref": "TestAgentRole522C6259" + "Ref": "TestAgentcrisRole15797E3B" } ] } }, - "TestAgent0DDFEE3E": { + "TestAgentcrisAgent395215F9": { "Type": "AWS::Bedrock::Agent", "Properties": { "ActionGroups": [ @@ -140,10 +244,10 @@ "SkipResourceInUseCheckOnDelete": false } ], - "AgentName": "test-agent", + "AgentName": "test-agent-cris", "AgentResourceRoleArn": { "Fn::GetAtt": [ - "TestAgentRole522C6259", + "TestAgentcrisRole15797E3B", "Arn" ] }, @@ -164,7 +268,7 @@ { "Ref": "AWS::AccountId" }, - ":inference-profile/us.anthropic.claude-3-sonnet-20240229-v1:0" + ":inference-profile/eu.anthropic.claude-3-sonnet-20240229-v1:0" ] ] }, @@ -192,7 +296,7 @@ { "Ref": "AWS::AccountId" }, - ":inference-profile/us.anthropic.claude-3-sonnet-20240229-v1:0" + ":inference-profile/eu.anthropic.claude-3-sonnet-20240229-v1:0" ] ] } @@ -204,6 +308,156 @@ } ] } + }, + "TestAgentaipRole6321FCB1": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "bedrock.amazonaws.com" + } + }, + { + "Action": "sts:AssumeRole", + "Condition": { + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + }, + "ArnLike": { + "aws:SourceArn": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":bedrock:eu-central-1:", + { + "Ref": "AWS::AccountId" + }, + ":agent/*" + ] + ] + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "bedrock.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "RoleName": "AmazonBedrockExecutionRoleForAgents_awscdkbedrstAgentaipB2FE765E" + } + }, + "TestAgentaipRoleDefaultPolicyD4F0F0D5": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "bedrock:InvokeModel", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":bedrock:*::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0" + ] + ] + } + }, + { + "Action": [ + "bedrock:GetInferenceProfile", + "bedrock:InvokeModel" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":bedrock:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":inference-profile/eu.anthropic.claude-3-sonnet-20240229-v1:0" + ] + ] + } + }, + { + "Action": [ + "bedrock:GetInferenceProfile", + "bedrock:InvokeModel" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "TestAppProfile97C615D8", + "InferenceProfileArn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "TestAgentaipRoleDefaultPolicyD4F0F0D5", + "Roles": [ + { + "Ref": "TestAgentaipRole6321FCB1" + } + ] + } + }, + "TestAgentaipAgent6B2B1F92": { + "Type": "AWS::Bedrock::Agent", + "Properties": { + "ActionGroups": [ + { + "ActionGroupName": "UserInputAction", + "ActionGroupState": "DISABLED", + "ParentActionGroupSignature": "AMAZON.UserInput", + "SkipResourceInUseCheckOnDelete": false + } + ], + "AgentName": "test-agent-aip", + "AgentResourceRoleArn": { + "Fn::GetAtt": [ + "TestAgentaipRole6321FCB1", + "Arn" + ] + }, + "Description": "test-description", + "FoundationModel": { + "Fn::GetAtt": [ + "TestAppProfile97C615D8", + "InferenceProfileArn" + ] + }, + "Instruction": "You are a test bot that needs to be very gentle and useful to the user" + } } }, "Parameters": { diff --git a/test/integ/inference-profiles.integ.ts b/test/integ/inference-profiles.integ.ts index 607afac4..5962bee5 100644 --- a/test/integ/inference-profiles.integ.ts +++ b/test/integ/inference-profiles.integ.ts @@ -10,55 +10,55 @@ * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions * and limitations under the License. */ -import * as integ from "@aws-cdk/integ-tests-alpha"; -import * as cdk from "aws-cdk-lib"; +import * as integ from '@aws-cdk/integ-tests-alpha'; +import * as cdk from 'aws-cdk-lib'; import { Agent, ApplicationInferenceProfile, BedrockFoundationModel, CrossRegionInferenceProfile, CrossRegionInferenceProfileRegion, -} from "../../src/cdk-lib/bedrock"; +} from '../../src/cdk-lib/bedrock'; const app = new cdk.App(); -const stack = new cdk.Stack(app, "aws-cdk-bedrock-guardrails-integ-test", { +const stack = new cdk.Stack(app, 'aws-cdk-bedrock-guardrails-integ-test', { env: { - region: "eu-central-1", + region: 'eu-central-1', }, }); -new Agent(stack, "TestAgent-simple", { - instruction: "You are a test bot that needs to be very gentle and useful to the user", +new Agent(stack, 'TestAgent-simple', { + instruction: 'You are a test bot that needs to be very gentle and useful to the user', foundationModel: BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0, - name: "test-agent-simple", - description: "test-description", + name: 'test-agent-simple', + description: 'test-description', }); -new Agent(stack, "TestAgent-cris", { - instruction: "You are a test bot that needs to be very gentle and useful to the user", +new Agent(stack, 'TestAgent-cris', { + instruction: 'You are a test bot that needs to be very gentle and useful to the user', foundationModel: CrossRegionInferenceProfile.fromConfig({ geoRegion: CrossRegionInferenceProfileRegion.EU, model: BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0, }), - name: "test-agent-cris", - description: "test-description", + name: 'test-agent-cris', + description: 'test-description', }); -const aip = new ApplicationInferenceProfile(stack, "TestAppProfile", { - inferenceProfileName: "my-app-inf-profile", - tags: [{ key: "projectId", value: "supplyUSXRC28" }], +const aip = new ApplicationInferenceProfile(stack, 'TestAppProfile', { + inferenceProfileName: 'my-app-inf-profile', + tags: [{ key: 'projectId', value: 'supplyUSXRC28' }], modelSource: CrossRegionInferenceProfile.fromConfig({ geoRegion: CrossRegionInferenceProfileRegion.EU, model: BedrockFoundationModel.ANTHROPIC_CLAUDE_SONNET_V1_0, }), }); -new Agent(stack, "TestAgent-aip", { - instruction: "You are a test bot that needs to be very gentle and useful to the user", +new Agent(stack, 'TestAgent-aip', { + instruction: 'You are a test bot that needs to be very gentle and useful to the user', foundationModel: aip, - name: "test-agent-aip", - description: "test-description", + name: 'test-agent-aip', + description: 'test-description', }); -new integ.IntegTest(app, "ServiceTest", { +new integ.IntegTest(app, 'ServiceTest', { testCases: [stack], cdkCommandOptions: { destroy: { From cf6621fdc9054c3321c404587e403728f80e6eba Mon Sep 17 00:00:00 2001 From: krokoko Date: Wed, 20 Nov 2024 12:09:13 -0600 Subject: [PATCH 22/22] chore(doc): update readme --- src/cdk-lib/bedrock/README.md | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/cdk-lib/bedrock/README.md b/src/cdk-lib/bedrock/README.md index 7fdc3c65..6c52eb1e 100644 --- a/src/cdk-lib/bedrock/README.md +++ b/src/cdk-lib/bedrock/README.md @@ -783,7 +783,7 @@ const agent = new bedrock.Agent(this, "Agent", { instruction: "You are a helpful and friendly agent that answers questions about literature.", }); -agent.addKnowledgeBase([kb]); +agent.addKnowledgeBase(kb); ``` Python @@ -798,6 +798,39 @@ agent = bedrock.Agent( agent.add_knowledge_base(kb); ``` +You can also use system defined inference profiles to enable cross region inference requests for supported models. For instance: + +TypeScript + +```ts +const cris = bedrock.CrossRegionInferenceProfile.fromConfig({ + geoRegion: bedrock.CrossRegionInferenceProfileRegion.US, + model: bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_3_5_SONNET_V1_0, +}); + +const agent = new bedrock.Agent(this, 'Agent', { + foundationModel: cris, + instruction: 'You are a helpful and friendly agent that answers questions about agriculture.' +}); + +``` +Python +```python +cris = bedrock.CrossRegionInferenceProfile.from_config( + geo_region= bedrock.CrossRegionInferenceProfileRegion.US, + model= bedrock.BedrockFoundationModel.ANTHROPIC_CLAUDE_3_5_SONNET_V1_0 +) + +agent = bedrock.Agent( + self, + "Agent", + foundation_model=cris, + instruction="You are a helpful and friendly agent that answers questions about agriculture.", +) +``` + +For more information on cross region inference, please refer to [System defined inference profiles](#system-defined-inference-profiles) + ### Action Groups An action group defines functions your agent can call. The functions are Lambda functions. The action group uses an OpenAPI schema to tell the agent what your functions do and how to call them.