Skip to content

Commit 16e8779

Browse files
jstrunkhvital
andauthored
feat(bedrock): replace PrepareAgent with shouldPrepareAgent prop (#250)
Co-authored-by: Heitor Vital <[email protected]>
1 parent e1cf010 commit 16e8779

17 files changed

+240
-259
lines changed

apidocs/classes/bedrock.Agent.md

+18-21
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,15 @@ Deploy a Bedrock Agent.
3030
- [aliasId](bedrock.Agent.md#aliasid)
3131
- [aliasName](bedrock.Agent.md#aliasname)
3232
- [cdkTagManager](bedrock.Agent.md#cdktagmanager)
33-
- [changeIds](bedrock.Agent.md#changeids)
3433
- [name](bedrock.Agent.md#name)
3534
- [node](bedrock.Agent.md#node)
36-
- [prepareAgent](bedrock.Agent.md#prepareagent)
35+
- [resourceUpdates](bedrock.Agent.md#resourceupdates)
3736
- [role](bedrock.Agent.md#role)
37+
- [shouldPrepareAgent](bedrock.Agent.md#shouldprepareagent)
3838

3939
### Methods
4040

41-
- [\_addPrepareAgentDependency](bedrock.Agent.md#_addprepareagentdependency)
41+
- [\_addAliasDependency](bedrock.Agent.md#_addaliasdependency)
4242
- [addActionGroup](bedrock.Agent.md#addactiongroup)
4343
- [addAlias](bedrock.Agent.md#addalias)
4444
- [toString](bedrock.Agent.md#tostring)
@@ -120,14 +120,6 @@ cdk.ITaggableV2.cdkTagManager
120120

121121
___
122122

123-
### changeIds
124-
125-
`Private` **changeIds**: `string`[] = `[]`
126-
127-
A list of values to indicate if PrepareAgent or an Alias needs to be updated.
128-
129-
___
130-
131123
### name
132124

133125
`Readonly` **name**: `string`
@@ -148,13 +140,11 @@ Construct.node
148140

149141
___
150142

151-
### prepareAgent
152-
153-
`Private` **prepareAgent**: `CustomResource`
143+
### resourceUpdates
154144

155-
The prepareAgent custom resource.
145+
`Private` **resourceUpdates**: `string`[] = `[]`
156146

157-
Add other resources as dependencies to ensure Prepare Agent is called after they are updated.
147+
A list of values to indicate if PrepareAgent or an Alias needs to be updated.
158148

159149
___
160150

@@ -164,20 +154,27 @@ ___
164154

165155
The IAM role for the agent.
166156

157+
___
158+
159+
### shouldPrepareAgent
160+
161+
`Private` `Readonly` **shouldPrepareAgent**: `boolean`
162+
163+
If prepare agent should be called on resource updates.
164+
167165
## Methods
168166

169-
### \_addPrepareAgentDependency
167+
### \_addAliasDependency
170168

171-
**_addPrepareAgentDependency**(`resource`, `changeId?`): `void`
169+
**_addAliasDependency**(`updatedAt`): `void`
172170

173-
Register a dependency for prepareAgent.
171+
Register a dependency for aliases.
174172

175173
#### Parameters
176174

177175
| Name | Type | Description |
178176
| :------ | :------ | :------ |
179-
| `resource` | `IResource` | The resource that will be registered as a dependency. |
180-
| `changeId?` | `string` | The changeId of the resource that will be registered as a dependency. This is an internal core function and should not be called directly. |
177+
| `updatedAt` | `string` | The updatedAt of the resource that will be registered as a dependency. This is an internal core function and should not be called directly. |
181178

182179
#### Returns
183180

apidocs/interfaces/bedrock.AgentActionGroupProps.md

+15
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
- [apiSchema](bedrock.AgentActionGroupProps.md#apischema)
1616
- [description](bedrock.AgentActionGroupProps.md#description)
1717
- [parentActionGroupSignature](bedrock.AgentActionGroupProps.md#parentactiongroupsignature)
18+
- [shouldPrepareAgent](bedrock.AgentActionGroupProps.md#shouldprepareagent)
1819

1920
## Properties
2021

@@ -84,3 +85,17 @@ ___
8485
If you specify this value as AMAZON.UserInput, the agent will prompt additional information from the user when it
8586
doesn't have enough information to respond to an utterance. Leave this field blank if you don't want the agent to
8687
prompt additional information.
88+
89+
___
90+
91+
### shouldPrepareAgent
92+
93+
`Optional` `Readonly` **shouldPrepareAgent**: `boolean`
94+
95+
Whether to prepare the agent for use.
96+
97+
**`Default`**
98+
99+
```ts
100+
- false
101+
```

apidocs/interfaces/bedrock.AgentAliasProps.md

+4-5
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
- [agentId](bedrock.AgentAliasProps.md#agentid)
1212
- [agentVersion](bedrock.AgentAliasProps.md#agentversion)
1313
- [aliasName](bedrock.AgentAliasProps.md#aliasname)
14-
- [changeIds](bedrock.AgentAliasProps.md#changeids)
14+
- [resourceUpdates](bedrock.AgentAliasProps.md#resourceupdates)
1515

1616
## Properties
1717

@@ -51,9 +51,8 @@ The name for the agent alias.
5151

5252
___
5353

54-
### changeIds
54+
### resourceUpdates
5555

56-
`Optional` `Readonly` **changeIds**: `string`[]
56+
`Optional` `Readonly` **resourceUpdates**: `string`[]
5757

58-
The list of change ids to let CloudFormation determine when to update the alias.
59-
A changeId is a hash of the properties of an agent, an agent/knowledge base association, or an action group.
58+
The list of resource update timestamps to let CloudFormation determine when to update the alias.

apidocs/interfaces/bedrock.AgentProps.md

+15
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Properties for a Bedrock Agent.
1919
- [knowledgeBases](bedrock.AgentProps.md#knowledgebases)
2020
- [name](bedrock.AgentProps.md#name)
2121
- [promptOverrideConfiguration](bedrock.AgentProps.md#promptoverrideconfiguration)
22+
- [shouldPrepareAgent](bedrock.AgentProps.md#shouldprepareagent)
2223

2324
## Properties
2425

@@ -133,3 +134,17 @@ Overrides for the agent.
133134
```ts
134135
- No overrides are provided.
135136
```
137+
138+
___
139+
140+
### shouldPrepareAgent
141+
142+
`Optional` `Readonly` **shouldPrepareAgent**: `boolean`
143+
144+
Whether to prepare the agent for use.
145+
146+
**`Default`**
147+
148+
```ts
149+
- false
150+
```

lambda/bedrock-custom-resources/custom_resources/__init__.py

-3
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
on_event as on_event_bedrock_agent_knowledgebase,
2727
)
2828
from .bedrock_agent_action_group import on_event as on_event_bedrock_agent_action_group
29-
from .bedrock_prepare_agent import on_event as on_event_bedrock_prepare_agent
3029

3130
LOG_LEVEL = os.getenv("LOG_LEVEL", "INFO")
3231

@@ -50,8 +49,6 @@ def on_event(event: CustomResourceRequest, context):
5049
return on_event_bedrock_knowledgebase(event, context)
5150
if resource_type == "Custom::Bedrock-DataSource":
5251
return on_event_bedrock_datasource(event, context)
53-
if resource_type == "Custom::Bedrock-PrepareAgent":
54-
return on_event_bedrock_prepare_agent(event, context)
5552
if resource_type == "Custom::NoOp":
5653
logger.info("NoOp resource type")
5754
# Return a response with a physical resource ID that is not empty.

lambda/bedrock-custom-resources/custom_resources/bedrock_agent.py

+32-35
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
# OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
1111
# and limitations under the License.
1212
#
13-
import pickle # nosec B403: pickle is used to create a hashable value. The value will never be deserialized.
14-
1513
import uuid
1614

1715
import boto3
@@ -27,6 +25,7 @@
2725

2826
from typing import TypedDict, NotRequired, Dict, Literal, Sequence
2927

28+
from .bedrock_prepare_agent import prepare_agent
3029
from .cr_types import CustomResourceRequest, CustomResourceResponse
3130
from .exceptions import AWSRetryableError, can_retry
3231

@@ -75,13 +74,14 @@ class AgentRequest(TypedDict):
7574
customerEncryptionKeyArn: NotRequired[str]
7675
promptOverrideConfiguration: NotRequired[PromptOverride]
7776
tags: NotRequired[Dict[str, str]]
77+
shouldPrepareAgent: NotRequired[str]
7878

7979

8080
class AgentResponse(TypedDict):
8181
agentId: str
8282
agentArn: NotRequired[str]
8383
agentName: NotRequired[str]
84-
changeId: NotRequired[str]
84+
updatedAt: NotRequired[str]
8585

8686

8787
session = boto3.session.Session()
@@ -170,23 +170,6 @@ def validate_agent_request(request: AgentRequest) -> AgentRequest:
170170
return request
171171

172172

173-
def create_change_hash(request: AgentRequest) -> str:
174-
return str(
175-
hash(
176-
# nosemgrep - Pickle is used to generate a hash. This object will never be deserialized.
177-
pickle.dumps(
178-
(
179-
request.get("instruction", None),
180-
request.get("foundationModel", None),
181-
request.get("description", None),
182-
request.get("idleSessionTTLInSeconds", None),
183-
request.get("promptOverrideConfiguration", None),
184-
)
185-
)
186-
)
187-
)
188-
189-
190173
def on_event(event: CustomResourceRequest[Dict], context):
191174
logger.debug(f"Received event: {event}")
192175
request_type = event["RequestType"]
@@ -213,23 +196,31 @@ def on_create(
213196
) -> CustomResourceResponse:
214197
bedrock_agent = session.client("bedrock-agent")
215198

199+
if "shouldPrepareAgent" in event["ResourceProperties"]:
200+
should_prepare_agent = event["ResourceProperties"]["shouldPrepareAgent"].upper() == 'TRUE'
201+
del event["ResourceProperties"]["shouldPrepareAgent"]
202+
else:
203+
should_prepare_agent = False
204+
216205
request = AgentRequest(**event["ResourceProperties"])
217206
request = validate_agent_request(request)
218207

219208
try:
220209
response = bedrock_agent.create_agent(clientToken=client_token, **request)
221-
return CustomResourceResponse(
210+
211+
except botocore.exceptions.ClientError as e:
212+
can_retry(e)
213+
if should_prepare_agent:
214+
prepare_agent(response["agent"]["agentId"])
215+
return CustomResourceResponse(
222216
PhysicalResourceId=response["agent"]["agentId"],
223217
Data=AgentResponse(
224218
agentArn=response["agent"]["agentArn"],
225219
agentId=response["agent"]["agentId"],
226220
agentName=response["agent"]["agentName"],
227-
changeId=create_change_hash(request),
221+
updatedAt=str(response["agent"]["updatedAt"]),
228222
),
229223
)
230-
except botocore.exceptions.ClientError as e:
231-
can_retry(e)
232-
233224

234225
@retry(
235226
retry=retry_if_exception_type(AWSRetryableError),
@@ -238,6 +229,11 @@ def on_create(
238229
)
239230
def on_update(event: CustomResourceRequest[Dict]) -> CustomResourceResponse:
240231
bedrock_agent = session.client("bedrock-agent")
232+
if "shouldPrepareAgent" in event["ResourceProperties"]:
233+
should_prepare_agent = event["ResourceProperties"]["shouldPrepareAgent"].upper() == 'TRUE'
234+
del event["ResourceProperties"]["shouldPrepareAgent"]
235+
else:
236+
should_prepare_agent = False
241237
request = AgentRequest(**event["ResourceProperties"])
242238
request = validate_agent_request(request)
243239
if "tags" in request:
@@ -248,18 +244,19 @@ def on_update(event: CustomResourceRequest[Dict]) -> CustomResourceResponse:
248244
**request,
249245
agentId=event["PhysicalResourceId"],
250246
)
251-
return CustomResourceResponse(
252-
PhysicalResourceId=response["agent"]["agentId"],
253-
Data=AgentResponse(
254-
agentArn=response["agent"]["agentArn"],
255-
agentId=response["agent"]["agentId"],
256-
agentName=response["agent"]["agentName"],
257-
changeId=create_change_hash(request),
258-
),
259-
)
260247
except botocore.exceptions.ClientError as e:
261248
can_retry(e)
262-
249+
if should_prepare_agent:
250+
prepare_agent(response["agent"]["agentId"])
251+
return CustomResourceResponse(
252+
PhysicalResourceId=response["agent"]["agentId"],
253+
Data=AgentResponse(
254+
agentArn=response["agent"]["agentArn"],
255+
agentId=response["agent"]["agentId"],
256+
agentName=response["agent"]["agentName"],
257+
updatedAt=str(response["agent"]["updatedAt"]),
258+
),
259+
)
263260

264261
@retry(
265262
retry=retry_if_exception_type(AWSRetryableError),

0 commit comments

Comments
 (0)