@aws/nx-plugin 1.0.0-rc.71 → 1.0.0-rc.73

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (168) hide show
  1. package/LICENSE-THIRD-PARTY +210 -730
  2. package/migrations.json +34 -19
  3. package/package.json +4 -4
  4. package/src/agentcore-gateway/__snapshots__/generator.spec.ts.snap +1 -1
  5. package/src/agentcore-harness/generator.d.ts +1 -1
  6. package/src/infra/app/__snapshots__/generator.spec.ts.snap +3 -3
  7. package/src/infra/app/generator.d.ts +1 -1
  8. package/src/init/generator.d.ts +1 -1
  9. package/src/license/config.d.ts +9 -0
  10. package/src/license/config.js +28 -0
  11. package/src/license/config.js.map +1 -1
  12. package/src/license/dependency-check/collectors/collector.js.map +1 -1
  13. package/src/license/dependency-check/evaluator.js +55 -10
  14. package/src/license/dependency-check/evaluator.js.map +1 -1
  15. package/src/license/generator.js +3 -17
  16. package/src/license/generator.js.map +1 -1
  17. package/src/license/known-exceptions.d.ts +0 -1
  18. package/src/license/known-exceptions.js +1 -23
  19. package/src/license/known-exceptions.js.map +1 -1
  20. package/src/migrations/latest/apt-security-updates-in-container-images/__snapshots__/migration.spec.ts.snap +90 -0
  21. package/src/migrations/latest/apt-security-updates-in-container-images/metadata.json +3 -0
  22. package/src/migrations/latest/apt-security-updates-in-container-images/migration.js +90 -0
  23. package/src/migrations/latest/apt-security-updates-in-container-images/migration.js.map +1 -0
  24. package/src/migrations/latest/remove-mcp-inspector-license-exceptions/metadata.json +3 -0
  25. package/src/migrations/latest/remove-mcp-inspector-license-exceptions/migration.d.ts +6 -0
  26. package/src/migrations/latest/remove-mcp-inspector-license-exceptions/migration.js +38 -0
  27. package/src/migrations/latest/remove-mcp-inspector-license-exceptions/migration.js.map +1 -0
  28. package/src/migrations/v1.0.0-rc.67/0001-smithy-server-package-rename/migration.js.map +1 -0
  29. package/src/migrations/v1.0.0-rc.68/0001-translate-script-whole-file-writes/migration.js.map +1 -0
  30. package/src/migrations/{latest/py-agent-a2a-lifespan-construction → v1.0.0-rc.70/0001-py-agent-a2a-lifespan-construction}/migration.js +14 -2
  31. package/src/migrations/v1.0.0-rc.70/0001-py-agent-a2a-lifespan-construction/migration.js.map +1 -0
  32. package/src/migrations/v1.0.0-rc.71/0001-py-agent-a2a-httpx-client-per-call/migration.d.ts +6 -0
  33. package/src/migrations/v1.0.0-rc.71/0001-py-agent-a2a-httpx-client-per-call/migration.js.map +1 -0
  34. package/src/migrations/v1.0.0-rc.72/0001-py-agent-session-management-support/metadata.json +3 -0
  35. package/src/migrations/v1.0.0-rc.72/0001-py-agent-session-management-support/migration.d.ts +2 -0
  36. package/src/migrations/v1.0.0-rc.72/0001-py-agent-session-management-support/migration.js +308 -0
  37. package/src/migrations/v1.0.0-rc.72/0001-py-agent-session-management-support/migration.js.map +1 -0
  38. package/src/preset/__snapshots__/generator.spec.ts.snap +2 -2
  39. package/src/preset/generator.d.ts +1 -1
  40. package/src/py/agent/__snapshots__/generator.constructs.spec.ts.snap +626 -10
  41. package/src/py/agent/__snapshots__/generator.core.spec.ts.snap +186 -0
  42. package/src/py/agent/__snapshots__/generator.frameworks.spec.ts.snap +55 -11
  43. package/src/py/agent/__snapshots__/generator.protocols.spec.ts.snap +669 -4
  44. package/src/py/agent/a2a-connection/generator.js +5 -11
  45. package/src/py/agent/a2a-connection/generator.js.map +1 -1
  46. package/src/py/agent/files/deploy/Dockerfile.template +7 -0
  47. package/src/py/agent/files/langchain/common/__init__.py.template +0 -0
  48. package/src/py/agent/files/langchain/common/agent.py.template +3 -3
  49. package/src/py/agent/files/langchain/common/session.py.template +61 -0
  50. package/src/py/agent/files/strands/ag-ui/main.py.template +5 -1
  51. package/src/py/agent/files/strands/common/agent.py.template +9 -2
  52. package/src/py/agent/files/strands/common/session.py.template +36 -0
  53. package/src/py/agent/generator.d.ts +11 -1
  54. package/src/py/agent/generator.js +78 -28
  55. package/src/py/agent/generator.js.map +1 -1
  56. package/src/py/agent/mcp-connection/__snapshots__/generator.spec.ts.snap +2 -0
  57. package/src/py/agent/react-connection/generator.d.ts +1 -1
  58. package/src/py/agent/schema.d.js.map +1 -1
  59. package/src/py/agent/schema.d.ts +1 -1
  60. package/src/py/agent/schema.json +3 -3
  61. package/src/py/fast-api/react/generator.d.ts +1 -1
  62. package/src/py/mcp-server/__snapshots__/generator.spec.ts.snap +5 -5
  63. package/src/py/mcp-server/files/deploy/Dockerfile.template +7 -0
  64. package/src/py/mcp-server/generator.js +8 -3
  65. package/src/py/mcp-server/generator.js.map +1 -1
  66. package/src/py/rdb/__snapshots__/generator.spec.ts.snap +7 -5
  67. package/src/py/rdb/generator.js +36 -2
  68. package/src/py/rdb/generator.js.map +1 -1
  69. package/src/smithy/project/__snapshots__/generator.spec.ts.snap +14 -14
  70. package/src/smithy/project/generator.d.ts +1 -1
  71. package/src/smithy/react-connection/generator.d.ts +1 -1
  72. package/src/smithy/ts/api/__snapshots__/generator.spec.ts.snap +1 -1
  73. package/src/terraform/project/generator.d.ts +1 -1
  74. package/src/trpc/react/generator.d.ts +1 -1
  75. package/src/ts/agent/__snapshots__/generator.spec.ts.snap +36 -8
  76. package/src/ts/agent/a2a-connection/generator.d.ts +1 -1
  77. package/src/ts/agent/a2a-connection/generator.js +4 -2
  78. package/src/ts/agent/a2a-connection/generator.js.map +1 -1
  79. package/src/ts/agent/files/deploy/Dockerfile.template +7 -0
  80. package/src/ts/agent/gateway-connection/generator.d.ts +1 -1
  81. package/src/ts/agent/mcp-connection/generator.d.ts +1 -1
  82. package/src/ts/agent/react-connection/generator.d.ts +1 -1
  83. package/src/ts/astro-docs/generator.d.ts +1 -1
  84. package/src/ts/dcr-proxy/generator.d.ts +1 -1
  85. package/src/ts/dynamodb/generator.d.ts +1 -1
  86. package/src/ts/lambda-function/generator.d.ts +1 -1
  87. package/src/ts/lib/generator.d.ts +1 -1
  88. package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +2 -2
  89. package/src/ts/mcp-server/files/Dockerfile.template +7 -0
  90. package/src/ts/mcp-server/generator.js +8 -3
  91. package/src/ts/mcp-server/generator.js.map +1 -1
  92. package/src/ts/nx-generator/generator.d.ts +1 -1
  93. package/src/ts/nx-migration/generator.d.ts +1 -1
  94. package/src/ts/nx-plugin/generator.d.ts +1 -1
  95. package/src/ts/rdb/__snapshots__/generator.spec.ts.snap +8 -6
  96. package/src/ts/rdb/generator.d.ts +1 -1
  97. package/src/ts/rdb/generator.js +29 -2
  98. package/src/ts/rdb/generator.js.map +1 -1
  99. package/src/ts/react-website/agui/generator.d.ts +1 -1
  100. package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +15 -15
  101. package/src/ts/react-website/app/generator.js +4 -2
  102. package/src/ts/react-website/app/generator.js.map +1 -1
  103. package/src/ts/react-website/cognito-auth/__snapshots__/generator.terraform.spec.ts.snap +1 -1
  104. package/src/utils/agent-connection/agent-connection.d.ts +10 -0
  105. package/src/utils/agent-connection/agent-connection.js +20 -9
  106. package/src/utils/agent-connection/agent-connection.js.map +1 -1
  107. package/src/utils/agent-connection/files/core-runtime-config/runtime-config.ts.template +5 -3
  108. package/src/utils/agent-connection/files/py-core-langchain/s3/s3_checkpoint_saver_langchain.py.template +360 -0
  109. package/src/utils/agent-connection/files/py-core-runtime-config/runtime_config.py.template +2 -4
  110. package/src/utils/agent-connection/files/py-core-strands/base/tool_errors_strands.py.template +24 -0
  111. package/src/utils/agent-core-constructs/agent-core-constructs.d.ts +1 -1
  112. package/src/utils/agent-core-constructs/agent-core-constructs.js.map +1 -1
  113. package/src/utils/agent-core-constructs/files/cdk/app/agent-core/__nameKebabCase__/__nameKebabCase__.ts.template +113 -13
  114. package/src/utils/agent-core-constructs/files/terraform/app/agent-core/__nameKebabCase__/__nameKebabCase__.tf.template +76 -7
  115. package/src/utils/ast.d.ts +29 -0
  116. package/src/utils/ast.js +31 -0
  117. package/src/utils/ast.js.map +1 -1
  118. package/src/utils/metrics.js +2 -2
  119. package/src/utils/metrics.js.map +1 -1
  120. package/src/utils/versions.d.ts +75 -72
  121. package/src/utils/versions.js +72 -69
  122. package/src/utils/versions.js.map +1 -1
  123. package/src/migrations/latest/py-agent-a2a-httpx-client-per-call/migration.js.map +0 -1
  124. package/src/migrations/latest/py-agent-a2a-lifespan-construction/migration.js.map +0 -1
  125. package/src/migrations/latest/smithy-server-package-rename/migration.js.map +0 -1
  126. package/src/migrations/latest/translate-script-whole-file-writes/migration.js.map +0 -1
  127. package/src/py/rdb/files/__name__/__init__.py.template +0 -3
  128. package/src/py/rdb/files/config.json.template +0 -14
  129. package/src/ts/rdb/files/config.json.template +0 -14
  130. package/src/ts/rdb/files/src/index.ts.template +0 -1
  131. /package/src/migrations/latest/{py-agent-a2a-httpx-client-per-call → apt-security-updates-in-container-images}/migration.d.ts +0 -0
  132. /package/src/migrations/{latest/smithy-server-package-rename → v1.0.0-rc.67/0001-smithy-server-package-rename}/metadata.json +0 -0
  133. /package/src/migrations/{latest/py-agent-a2a-lifespan-construction → v1.0.0-rc.67/0001-smithy-server-package-rename}/migration.d.ts +0 -0
  134. /package/src/migrations/{latest/smithy-server-package-rename → v1.0.0-rc.67/0001-smithy-server-package-rename}/migration.js +0 -0
  135. /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/files/build-system-prompt.ts.fixture +0 -0
  136. /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/files/build-user-prompt.ts.fixture +0 -0
  137. /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/files/config-path.ts.fixture +0 -0
  138. /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/files/file-to-translate.ts.fixture +0 -0
  139. /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/files/get-files-to-translate.ts.fixture +0 -0
  140. /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/files/header.ts.fixture +0 -0
  141. /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/files/log.ts.fixture +0 -0
  142. /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/files/main-call.ts.fixture +0 -0
  143. /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/files/main.ts.fixture +0 -0
  144. /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/files/project-root.ts.fixture +0 -0
  145. /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/files/run-with-concurrency.ts.fixture +0 -0
  146. /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/files/scripts-dir.ts.fixture +0 -0
  147. /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/files/translate-file-for-language.ts.fixture +0 -0
  148. /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/grit/already-migrated.grit +0 -0
  149. /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/grit/build-system-prompt.grit +0 -0
  150. /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/grit/build-user-prompt.grit +0 -0
  151. /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/grit/config-path.grit +0 -0
  152. /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/grit/file-to-translate.grit +0 -0
  153. /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/grit/get-files-to-translate.grit +0 -0
  154. /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/grit/log.grit +0 -0
  155. /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/grit/main-call.grit +0 -0
  156. /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/grit/main.grit +0 -0
  157. /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/grit/project-root.grit +0 -0
  158. /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/grit/run-with-concurrency.grit +0 -0
  159. /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/grit/translate-file-for-language.grit +0 -0
  160. /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/metadata.json +0 -0
  161. /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/migration.d.ts +0 -0
  162. /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/migration.js +0 -0
  163. /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/test-fixtures/released-script-first.ts.fixture +0 -0
  164. /package/src/migrations/{latest/translate-script-whole-file-writes → v1.0.0-rc.68/0001-translate-script-whole-file-writes}/test-fixtures/released-script.ts.fixture +0 -0
  165. /package/src/migrations/{latest/py-agent-a2a-lifespan-construction → v1.0.0-rc.70/0001-py-agent-a2a-lifespan-construction}/metadata.json +0 -0
  166. /package/src/migrations/{latest/smithy-server-package-rename → v1.0.0-rc.70/0001-py-agent-a2a-lifespan-construction}/migration.d.ts +0 -0
  167. /package/src/migrations/{latest/py-agent-a2a-httpx-client-per-call → v1.0.0-rc.71/0001-py-agent-a2a-httpx-client-per-call}/metadata.json +0 -0
  168. /package/src/migrations/{latest/py-agent-a2a-httpx-client-per-call → v1.0.0-rc.71/0001-py-agent-a2a-httpx-client-per-call}/migration.js +0 -0
@@ -1,8 +1,338 @@
1
1
  // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
2
 
3
+ exports[`py#agent generator > should create DynamoDB checkpoint table and S3 offload bucket infrastructure when session is dynamodb-s3 > agent-construct.ts (dynamodb-s3) 1`] = `
4
+ "import { Fn, Lazy, Names, RemovalPolicy, Stack } from 'aws-cdk-lib';
5
+ import { Platform } from 'aws-cdk-lib/aws-ecr-assets';
6
+ import { Connections, IConnectable } from 'aws-cdk-lib/aws-ec2';
7
+ import {
8
+ BlockPublicAccess,
9
+ Bucket,
10
+ BucketEncryption,
11
+ } from 'aws-cdk-lib/aws-s3';
12
+ import { Key } from 'aws-cdk-lib/aws-kms';
13
+ import {
14
+ CfnDelivery,
15
+ CfnDeliveryDestination,
16
+ CfnDeliverySource,
17
+ LogGroup,
18
+ RetentionDays,
19
+ } from 'aws-cdk-lib/aws-logs';
20
+ import {
21
+ AttributeType,
22
+ BillingMode,
23
+ Table,
24
+ TableEncryption,
25
+ } from 'aws-cdk-lib/aws-dynamodb';
26
+ import { Construct } from 'constructs';
27
+ import * as path from 'path';
28
+ import * as url from 'url';
29
+ import {
30
+ AgentRuntimeArtifact,
31
+ ProtocolType,
32
+ Runtime,
33
+ RuntimeProps,
34
+ } from 'aws-cdk-lib/aws-bedrockagentcore';
35
+ import {
36
+ PolicyStatement,
37
+ Effect,
38
+ ServicePrincipal,
39
+ IGrantable,
40
+ IPrincipal,
41
+ Grant,
42
+ } from 'aws-cdk-lib/aws-iam';
43
+ import { suppressRules } from '../../../core/checkov.js';
44
+ import { RuntimeConfig } from '../../../core/runtime-config.js';
45
+ import { findWorkspaceRoot } from '../../../core/workspace.js';
46
+
47
+ export type DynamodbAgentProps = Omit<
48
+ RuntimeProps,
49
+ | 'runtimeName'
50
+ | 'protocolConfiguration'
51
+ | 'agentRuntimeArtifact'
52
+ | 'authorizerConfiguration'
53
+ > & {
54
+ /**
55
+ * Removal policy for the session bucket holding the agent's conversation
56
+ * history. Defaults to retaining it so a stack \`destroy\` doesn't silently
57
+ * delete session data — set to \`RemovalPolicy.DESTROY\` for sandbox/CI teardown.
58
+ *
59
+ * @default RemovalPolicy.RETAIN
60
+ */
61
+ readonly sessionBucketRemovalPolicy?: RemovalPolicy;
62
+ /**
63
+ * Whether to enable deletion protection on the session checkpoint table.
64
+ * Set to \`false\` to allow a stack \`destroy\` to remove it (e.g. for
65
+ * sandbox/CI teardown).
66
+ *
67
+ * @default true
68
+ */
69
+ readonly sessionTableDeletionProtection?: boolean;
70
+ /**
71
+ * Removal policy for the session checkpoint table.
72
+ *
73
+ * @default RemovalPolicy.RETAIN
74
+ */
75
+ readonly sessionTableRemovalPolicy?: RemovalPolicy;
76
+ };
77
+
78
+ export class DynamodbAgent
79
+ extends Construct
80
+ implements IGrantable, IConnectable
81
+ {
82
+ public readonly dockerImage: AgentRuntimeArtifact;
83
+ public readonly agentCoreRuntime: Runtime;
84
+ /** Default Gateway target name for this agent. */
85
+ public readonly agentName = 'dynamodb-agent';
86
+ /** Inbound auth — a fronting Gateway uses this to pick its outbound credential. */
87
+ public readonly auth = 'iam';
88
+
89
+ constructor(scope: Construct, id: string, props?: DynamodbAgentProps) {
90
+ super(scope, id);
91
+
92
+ const rc = RuntimeConfig.ensure(this);
93
+
94
+ // Resolve the bundle output directory containing the Dockerfile and built artifacts
95
+ const bundleDir = path.join(
96
+ findWorkspaceRoot(url.fileURLToPath(new URL(import.meta.url))),
97
+ 'dist/apps/test-project/docker/dynamodb-agent',
98
+ );
99
+
100
+ this.dockerImage = AgentRuntimeArtifact.fromAsset(bundleDir, {
101
+ platform: Platform.LINUX_ARM64,
102
+ });
103
+
104
+ const {
105
+ sessionBucketRemovalPolicy = RemovalPolicy.RETAIN,
106
+ sessionTableDeletionProtection = true,
107
+ sessionTableRemovalPolicy = RemovalPolicy.RETAIN,
108
+ ...restProps
109
+ } = props ?? {};
110
+
111
+ const sessionKey = new Key(this, 'SessionKey', {
112
+ enableKeyRotation: true,
113
+ });
114
+
115
+ // Allow CloudWatch Logs to use the session key for server access log delivery.
116
+ const stack = Stack.of(this);
117
+ sessionKey.addToResourcePolicy(
118
+ new PolicyStatement({
119
+ effect: Effect.ALLOW,
120
+ principals: [
121
+ new ServicePrincipal(\`logs.\${stack.region}.amazonaws.com\`),
122
+ ],
123
+ actions: [
124
+ 'kms:Encrypt',
125
+ 'kms:Decrypt',
126
+ 'kms:ReEncrypt*',
127
+ 'kms:GenerateDataKey*',
128
+ 'kms:DescribeKey',
129
+ ],
130
+ resources: ['*'],
131
+ conditions: {
132
+ ArnLike: {
133
+ 'kms:EncryptionContext:aws:logs:arn': \`arn:aws:logs:\${stack.region}:\${stack.account}:log-group:*\`,
134
+ },
135
+ },
136
+ }),
137
+ );
138
+
139
+ const sessionAccessLogs = new LogGroup(this, 'SessionAccessLogs', {
140
+ retention: RetentionDays.ONE_YEAR,
141
+ encryptionKey: sessionKey,
142
+ removalPolicy: RemovalPolicy.DESTROY,
143
+ });
144
+
145
+ const sessionBucket = new Bucket(this, 'SessionBucket', {
146
+ enforceSSL: true,
147
+ removalPolicy: sessionBucketRemovalPolicy,
148
+ encryption: BucketEncryption.KMS,
149
+ encryptionKey: sessionKey,
150
+ blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
151
+ });
152
+ suppressRules(
153
+ sessionBucket,
154
+ ['CKV_AWS_21'],
155
+ 'Session data does not need versioning enabled',
156
+ );
157
+ suppressRules(
158
+ sessionBucket,
159
+ ['CKV2_AWS_61'],
160
+ 'Lifecycle configuration not required for session data',
161
+ );
162
+ suppressRules(
163
+ sessionBucket,
164
+ ['CKV_AWS_144'],
165
+ 'Cross-region replication not required for session data',
166
+ );
167
+ suppressRules(
168
+ sessionBucket,
169
+ ['CKV2_AWS_62'],
170
+ 'Event notifications not required for session data',
171
+ );
172
+ suppressRules(
173
+ sessionBucket,
174
+ ['CKV_AWS_18'],
175
+ 'Server access logs are delivered to CloudWatch Logs',
176
+ );
177
+
178
+ const sessionAccessLogsSource: CfnDeliverySource = new CfnDeliverySource(
179
+ this,
180
+ 'SessionAccessLogsSource',
181
+ {
182
+ name: Lazy.string({
183
+ produce: () =>
184
+ Names.uniqueResourceName(sessionAccessLogsSource, {
185
+ maxLength: 60,
186
+ }),
187
+ }),
188
+ logType: 'S3_SERVER_ACCESS_LOGS',
189
+ resourceArn: sessionBucket.bucketArn,
190
+ },
191
+ );
192
+ const sessionBucketPolicy = sessionBucket.policy;
193
+ if (sessionBucketPolicy) {
194
+ sessionAccessLogsSource.node.addDependency(sessionBucketPolicy);
195
+ }
196
+ const sessionAccessLogsDestination: CfnDeliveryDestination =
197
+ new CfnDeliveryDestination(this, 'SessionAccessLogsDestination', {
198
+ name: Lazy.string({
199
+ produce: () =>
200
+ Names.uniqueResourceName(sessionAccessLogsDestination, {
201
+ maxLength: 60,
202
+ }),
203
+ }),
204
+ destinationResourceArn: sessionAccessLogs.logGroupArn,
205
+ });
206
+ const sessionAccessLogsDelivery = new CfnDelivery(
207
+ this,
208
+ 'SessionAccessLogsDelivery',
209
+ {
210
+ deliverySourceName: sessionAccessLogsSource.name,
211
+ deliveryDestinationArn: sessionAccessLogsDestination.attrArn,
212
+ },
213
+ );
214
+ sessionAccessLogsDelivery.addDependency(sessionAccessLogsSource);
215
+
216
+ // Unified checkpoints/writes table, matching the schema
217
+ // langgraph_checkpoint_aws.DynamoDBSaver expects (PK/SK, TTL on \`ttl\`).
218
+ const sessionTable = new Table(this, 'SessionTable', {
219
+ partitionKey: { name: 'PK', type: AttributeType.STRING },
220
+ sortKey: { name: 'SK', type: AttributeType.STRING },
221
+ billingMode: BillingMode.PAY_PER_REQUEST,
222
+ pointInTimeRecoverySpecification: { pointInTimeRecoveryEnabled: true },
223
+ timeToLiveAttribute: 'ttl',
224
+ encryption: TableEncryption.CUSTOMER_MANAGED,
225
+ encryptionKey: sessionKey,
226
+ deletionProtection: sessionTableDeletionProtection,
227
+ removalPolicy: sessionTableRemovalPolicy,
228
+ });
229
+
230
+ this.agentCoreRuntime = new Runtime(this, 'DynamodbAgent', {
231
+ runtimeName: Lazy.string({
232
+ produce: () =>
233
+ Names.uniqueResourceName(this.agentCoreRuntime, { maxLength: 40 }),
234
+ }),
235
+ protocolConfiguration: ProtocolType.HTTP,
236
+ agentRuntimeArtifact: this.dockerImage,
237
+ ...restProps,
238
+ environmentVariables: {
239
+ RUNTIME_CONFIG_APP_ID: rc.appConfigApplicationId,
240
+ ...restProps?.environmentVariables,
241
+ },
242
+ });
243
+
244
+ // Grant access for the agent to invoke bedrock models
245
+ this.agentCoreRuntime.addToRolePolicy(
246
+ new PolicyStatement({
247
+ actions: [
248
+ 'bedrock:InvokeModel',
249
+ 'bedrock:InvokeModelWithResponseStream',
250
+ ],
251
+ resources: [
252
+ 'arn:aws:bedrock:*:*:foundation-model/*',
253
+ 'arn:aws:bedrock:*:*:inference-profile/*',
254
+ ],
255
+ }),
256
+ );
257
+
258
+ sessionTable.grantReadWriteData(this.agentCoreRuntime);
259
+ sessionBucket.grantReadWrite(this.agentCoreRuntime);
260
+
261
+ rc.grantReadAppConfig(this.agentCoreRuntime);
262
+
263
+ rc.set('agentcore', 'agentRuntimes', {
264
+ ...rc.get('agentcore').agentRuntimes,
265
+ DynamodbAgent: {
266
+ arn: this.agentCoreRuntime.agentRuntimeArn,
267
+ session: {
268
+ tableName: sessionTable.tableName,
269
+ bucketName: sessionBucket.bucketName,
270
+ },
271
+ },
272
+ });
273
+ }
274
+
275
+ /**
276
+ * The principal to grant permissions to.
277
+ */
278
+ public get grantPrincipal(): IPrincipal {
279
+ return this.agentCoreRuntime.grantPrincipal;
280
+ }
281
+
282
+ /**
283
+ * Network connections for this agent runtime.
284
+ */
285
+ public get connections(): Connections {
286
+ return this.agentCoreRuntime.connections;
287
+ }
288
+
289
+ /**
290
+ * The HTTPS invocation URL of the runtime.
291
+ */
292
+ public get invocationUrl(): string {
293
+ // The URL must URL-encode the runtime ARN (':' -> '%3A', '/' -> '%2F').
294
+ // The ARN is a CDK token, so encode at deploy time via Fn.join/Fn.split.
295
+ const encodedArn = Fn.join(
296
+ '%2F',
297
+ Fn.split(
298
+ '/',
299
+ Fn.join('%3A', Fn.split(':', this.agentCoreRuntime.agentRuntimeArn)),
300
+ ),
301
+ );
302
+ return \`https://bedrock-agentcore.\${Stack.of(this).region}.amazonaws.com/runtimes/\${encodedArn}/invocations?qualifier=DEFAULT\`;
303
+ }
304
+
305
+ /**
306
+ * Grants IAM permissions to invoke this agent runtime.
307
+ *
308
+ * @param grantee - The IAM principal to grant permissions to
309
+ */
310
+ public grantInvokeAccess(grantee: IGrantable) {
311
+ this.agentCoreRuntime.grantInvoke(grantee);
312
+
313
+ Grant.addToPrincipal({
314
+ grantee,
315
+ actions: ['bedrock-agentcore:InvokeAgentRuntimeWithWebSocketStream'],
316
+ resourceArns: [
317
+ this.agentCoreRuntime.agentRuntimeArn,
318
+ \`\${this.agentCoreRuntime.agentRuntimeArn}/*\`,
319
+ ],
320
+ });
321
+ }
322
+ }
323
+ "
324
+ `;
325
+
3
326
  exports[`py#agent generator > should match snapshot for BedrockAgentCoreRuntime generated constructs files > agent-Dockerfile 1`] = `
4
327
  "FROM public.ecr.aws/docker/library/python:3.14-slim
5
328
 
329
+ # Apply the distribution's security updates: base image tags lag behind the
330
+ # security suite, so its OS packages carry fixed HIGH/CRITICAL vulnerabilities
331
+ # flagged by the image scan.
332
+ RUN apt-get update && \\
333
+ apt-get upgrade -y --no-install-recommends && \\
334
+ rm -rf /var/lib/apt/lists/*
335
+
6
336
  # Remove the base image's pip: the agent runs from the bundled environment and
7
337
  # never needs it at runtime, and pip's vendored packages carry known
8
338
  # HIGH/CRITICAL vulnerabilities flagged by the image scan.
@@ -27,9 +357,22 @@ CMD ["python", "bin/opentelemetry-instrument", "python", "-m", "proj_test_projec
27
357
  `;
28
358
 
29
359
  exports[`py#agent generator > should match snapshot for BedrockAgentCoreRuntime generated constructs files > agent-construct.ts 1`] = `
30
- "import { Fn, Lazy, Names, Stack } from 'aws-cdk-lib';
360
+ "import { Fn, Lazy, Names, RemovalPolicy, Stack } from 'aws-cdk-lib';
31
361
  import { Platform } from 'aws-cdk-lib/aws-ecr-assets';
32
362
  import { Connections, IConnectable } from 'aws-cdk-lib/aws-ec2';
363
+ import {
364
+ BlockPublicAccess,
365
+ Bucket,
366
+ BucketEncryption,
367
+ } from 'aws-cdk-lib/aws-s3';
368
+ import { Key } from 'aws-cdk-lib/aws-kms';
369
+ import {
370
+ CfnDelivery,
371
+ CfnDeliveryDestination,
372
+ CfnDeliverySource,
373
+ LogGroup,
374
+ RetentionDays,
375
+ } from 'aws-cdk-lib/aws-logs';
33
376
  import { Construct } from 'constructs';
34
377
  import * as path from 'path';
35
378
  import * as url from 'url';
@@ -41,10 +384,13 @@ import {
41
384
  } from 'aws-cdk-lib/aws-bedrockagentcore';
42
385
  import {
43
386
  PolicyStatement,
387
+ Effect,
388
+ ServicePrincipal,
44
389
  IGrantable,
45
390
  IPrincipal,
46
391
  Grant,
47
392
  } from 'aws-cdk-lib/aws-iam';
393
+ import { suppressRules } from '../../../core/checkov.js';
48
394
  import { RuntimeConfig } from '../../../core/runtime-config.js';
49
395
  import { findWorkspaceRoot } from '../../../core/workspace.js';
50
396
 
@@ -54,7 +400,16 @@ export type SnapshotBedrockAgentProps = Omit<
54
400
  | 'protocolConfiguration'
55
401
  | 'agentRuntimeArtifact'
56
402
  | 'authorizerConfiguration'
57
- >;
403
+ > & {
404
+ /**
405
+ * Removal policy for the session bucket holding the agent's conversation
406
+ * history. Defaults to retaining it so a stack \`destroy\` doesn't silently
407
+ * delete session data — set to \`RemovalPolicy.DESTROY\` for sandbox/CI teardown.
408
+ *
409
+ * @default RemovalPolicy.RETAIN
410
+ */
411
+ readonly sessionBucketRemovalPolicy?: RemovalPolicy;
412
+ };
58
413
 
59
414
  export class SnapshotBedrockAgent
60
415
  extends Construct
@@ -82,6 +437,114 @@ export class SnapshotBedrockAgent
82
437
  platform: Platform.LINUX_ARM64,
83
438
  });
84
439
 
440
+ const { sessionBucketRemovalPolicy = RemovalPolicy.RETAIN, ...restProps } =
441
+ props ?? {};
442
+
443
+ const sessionKey = new Key(this, 'SessionKey', {
444
+ enableKeyRotation: true,
445
+ });
446
+
447
+ // Allow CloudWatch Logs to use the session key for server access log delivery.
448
+ const stack = Stack.of(this);
449
+ sessionKey.addToResourcePolicy(
450
+ new PolicyStatement({
451
+ effect: Effect.ALLOW,
452
+ principals: [
453
+ new ServicePrincipal(\`logs.\${stack.region}.amazonaws.com\`),
454
+ ],
455
+ actions: [
456
+ 'kms:Encrypt',
457
+ 'kms:Decrypt',
458
+ 'kms:ReEncrypt*',
459
+ 'kms:GenerateDataKey*',
460
+ 'kms:DescribeKey',
461
+ ],
462
+ resources: ['*'],
463
+ conditions: {
464
+ ArnLike: {
465
+ 'kms:EncryptionContext:aws:logs:arn': \`arn:aws:logs:\${stack.region}:\${stack.account}:log-group:*\`,
466
+ },
467
+ },
468
+ }),
469
+ );
470
+
471
+ const sessionAccessLogs = new LogGroup(this, 'SessionAccessLogs', {
472
+ retention: RetentionDays.ONE_YEAR,
473
+ encryptionKey: sessionKey,
474
+ removalPolicy: RemovalPolicy.DESTROY,
475
+ });
476
+
477
+ const sessionBucket = new Bucket(this, 'SessionBucket', {
478
+ enforceSSL: true,
479
+ removalPolicy: sessionBucketRemovalPolicy,
480
+ encryption: BucketEncryption.KMS,
481
+ encryptionKey: sessionKey,
482
+ blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
483
+ });
484
+ suppressRules(
485
+ sessionBucket,
486
+ ['CKV_AWS_21'],
487
+ 'Session data does not need versioning enabled',
488
+ );
489
+ suppressRules(
490
+ sessionBucket,
491
+ ['CKV2_AWS_61'],
492
+ 'Lifecycle configuration not required for session data',
493
+ );
494
+ suppressRules(
495
+ sessionBucket,
496
+ ['CKV_AWS_144'],
497
+ 'Cross-region replication not required for session data',
498
+ );
499
+ suppressRules(
500
+ sessionBucket,
501
+ ['CKV2_AWS_62'],
502
+ 'Event notifications not required for session data',
503
+ );
504
+ suppressRules(
505
+ sessionBucket,
506
+ ['CKV_AWS_18'],
507
+ 'Server access logs are delivered to CloudWatch Logs',
508
+ );
509
+
510
+ const sessionAccessLogsSource: CfnDeliverySource = new CfnDeliverySource(
511
+ this,
512
+ 'SessionAccessLogsSource',
513
+ {
514
+ name: Lazy.string({
515
+ produce: () =>
516
+ Names.uniqueResourceName(sessionAccessLogsSource, {
517
+ maxLength: 60,
518
+ }),
519
+ }),
520
+ logType: 'S3_SERVER_ACCESS_LOGS',
521
+ resourceArn: sessionBucket.bucketArn,
522
+ },
523
+ );
524
+ const sessionBucketPolicy = sessionBucket.policy;
525
+ if (sessionBucketPolicy) {
526
+ sessionAccessLogsSource.node.addDependency(sessionBucketPolicy);
527
+ }
528
+ const sessionAccessLogsDestination: CfnDeliveryDestination =
529
+ new CfnDeliveryDestination(this, 'SessionAccessLogsDestination', {
530
+ name: Lazy.string({
531
+ produce: () =>
532
+ Names.uniqueResourceName(sessionAccessLogsDestination, {
533
+ maxLength: 60,
534
+ }),
535
+ }),
536
+ destinationResourceArn: sessionAccessLogs.logGroupArn,
537
+ });
538
+ const sessionAccessLogsDelivery = new CfnDelivery(
539
+ this,
540
+ 'SessionAccessLogsDelivery',
541
+ {
542
+ deliverySourceName: sessionAccessLogsSource.name,
543
+ deliveryDestinationArn: sessionAccessLogsDestination.attrArn,
544
+ },
545
+ );
546
+ sessionAccessLogsDelivery.addDependency(sessionAccessLogsSource);
547
+
85
548
  this.agentCoreRuntime = new Runtime(this, 'SnapshotBedrockAgent', {
86
549
  runtimeName: Lazy.string({
87
550
  produce: () =>
@@ -89,10 +552,10 @@ export class SnapshotBedrockAgent
89
552
  }),
90
553
  protocolConfiguration: ProtocolType.HTTP,
91
554
  agentRuntimeArtifact: this.dockerImage,
92
- ...props,
555
+ ...restProps,
93
556
  environmentVariables: {
94
557
  RUNTIME_CONFIG_APP_ID: rc.appConfigApplicationId,
95
- ...props?.environmentVariables,
558
+ ...restProps?.environmentVariables,
96
559
  },
97
560
  });
98
561
 
@@ -110,12 +573,17 @@ export class SnapshotBedrockAgent
110
573
  }),
111
574
  );
112
575
 
576
+ sessionBucket.grantReadWrite(this.agentCoreRuntime);
577
+
113
578
  rc.grantReadAppConfig(this.agentCoreRuntime);
114
579
 
115
580
  rc.set('agentcore', 'agentRuntimes', {
116
581
  ...rc.get('agentcore').agentRuntimes,
117
582
  SnapshotBedrockAgent: {
118
583
  arn: this.agentCoreRuntime.agentRuntimeArn,
584
+ session: {
585
+ bucketName: sessionBucket.bucketName,
586
+ },
119
587
  },
120
588
  });
121
589
  }
@@ -195,10 +663,12 @@ exports[`py#agent generator > should match snapshot for generated files > agent-
195
663
  exports[`py#agent generator > should match snapshot for generated files > agent-agent.py 1`] = `
196
664
  "from contextlib import contextmanager
197
665
 
198
- from proj_agent_connection import log_model_errors
666
+ from proj_agent_connection import log_model_errors, log_tool_errors
199
667
  from strands import Agent, tool
200
668
  from strands_tools import current_time
201
669
 
670
+ from .session import get_session_manager
671
+
202
672
 
203
673
  @tool
204
674
  def subtract(a: int, b: int) -> int:
@@ -216,7 +686,8 @@ Use your tools for mathematical tasks.
216
686
  Refer to tools as your 'spellbook'.
217
687
  """,
218
688
  tools=[subtract, current_time],
219
- hooks=[log_model_errors],
689
+ hooks=[log_model_errors, log_tool_errors],
690
+ session_manager=get_session_manager(),
220
691
  )
221
692
  "
222
693
  `;
@@ -303,15 +774,15 @@ name = "proj.test_project"
303
774
  version = "0.1.0"
304
775
  dependencies = [
305
776
  "proj-agent-connection",
306
- "aws-lambda-powertools==3.31.1",
777
+ "aws-lambda-powertools==3.34.0",
307
778
  "aws-opentelemetry-distro==0.19.0",
308
779
  "bedrock-agentcore==1.21.0",
309
- "boto3==1.43.67",
780
+ "boto3==1.43.72",
310
781
  "fastapi==0.141.1",
311
782
  "mcp==1.28.1",
312
- "strands-agents==1.51.0",
783
+ "strands-agents==1.52.0",
313
784
  "strands-agents-tools==0.8.6",
314
- "uvicorn==0.52.1"
785
+ "uvicorn==0.52.3"
315
786
  ]
316
787
 
317
788
  [dependency-groups]
@@ -324,3 +795,148 @@ dev-dependencies = [ ]
324
795
  workspace = true
325
796
  "
326
797
  `;
798
+
799
+ exports[`py#agent generator > should not create session bucket infrastructure when session is in-memory > agent-construct.ts (in-memory) 1`] = `
800
+ "import { Fn, Lazy, Names, Stack } from 'aws-cdk-lib';
801
+ import { Platform } from 'aws-cdk-lib/aws-ecr-assets';
802
+ import { Connections, IConnectable } from 'aws-cdk-lib/aws-ec2';
803
+ import { Construct } from 'constructs';
804
+ import * as path from 'path';
805
+ import * as url from 'url';
806
+ import {
807
+ AgentRuntimeArtifact,
808
+ ProtocolType,
809
+ Runtime,
810
+ RuntimeProps,
811
+ } from 'aws-cdk-lib/aws-bedrockagentcore';
812
+ import {
813
+ PolicyStatement,
814
+ IGrantable,
815
+ IPrincipal,
816
+ Grant,
817
+ } from 'aws-cdk-lib/aws-iam';
818
+ import { RuntimeConfig } from '../../../core/runtime-config.js';
819
+ import { findWorkspaceRoot } from '../../../core/workspace.js';
820
+
821
+ export type InMemoryAgentProps = Omit<
822
+ RuntimeProps,
823
+ | 'runtimeName'
824
+ | 'protocolConfiguration'
825
+ | 'agentRuntimeArtifact'
826
+ | 'authorizerConfiguration'
827
+ >;
828
+
829
+ export class InMemoryAgent
830
+ extends Construct
831
+ implements IGrantable, IConnectable
832
+ {
833
+ public readonly dockerImage: AgentRuntimeArtifact;
834
+ public readonly agentCoreRuntime: Runtime;
835
+ /** Default Gateway target name for this agent. */
836
+ public readonly agentName = 'in-memory-agent';
837
+ /** Inbound auth — a fronting Gateway uses this to pick its outbound credential. */
838
+ public readonly auth = 'iam';
839
+
840
+ constructor(scope: Construct, id: string, props?: InMemoryAgentProps) {
841
+ super(scope, id);
842
+
843
+ const rc = RuntimeConfig.ensure(this);
844
+
845
+ // Resolve the bundle output directory containing the Dockerfile and built artifacts
846
+ const bundleDir = path.join(
847
+ findWorkspaceRoot(url.fileURLToPath(new URL(import.meta.url))),
848
+ 'dist/apps/test-project/docker/in-memory-agent',
849
+ );
850
+
851
+ this.dockerImage = AgentRuntimeArtifact.fromAsset(bundleDir, {
852
+ platform: Platform.LINUX_ARM64,
853
+ });
854
+
855
+ this.agentCoreRuntime = new Runtime(this, 'InMemoryAgent', {
856
+ runtimeName: Lazy.string({
857
+ produce: () =>
858
+ Names.uniqueResourceName(this.agentCoreRuntime, { maxLength: 40 }),
859
+ }),
860
+ protocolConfiguration: ProtocolType.HTTP,
861
+ agentRuntimeArtifact: this.dockerImage,
862
+ ...props,
863
+ environmentVariables: {
864
+ RUNTIME_CONFIG_APP_ID: rc.appConfigApplicationId,
865
+ ...props?.environmentVariables,
866
+ },
867
+ });
868
+
869
+ // Grant access for the agent to invoke bedrock models
870
+ this.agentCoreRuntime.addToRolePolicy(
871
+ new PolicyStatement({
872
+ actions: [
873
+ 'bedrock:InvokeModel',
874
+ 'bedrock:InvokeModelWithResponseStream',
875
+ ],
876
+ resources: [
877
+ 'arn:aws:bedrock:*:*:foundation-model/*',
878
+ 'arn:aws:bedrock:*:*:inference-profile/*',
879
+ ],
880
+ }),
881
+ );
882
+
883
+ rc.grantReadAppConfig(this.agentCoreRuntime);
884
+
885
+ rc.set('agentcore', 'agentRuntimes', {
886
+ ...rc.get('agentcore').agentRuntimes,
887
+ InMemoryAgent: {
888
+ arn: this.agentCoreRuntime.agentRuntimeArn,
889
+ },
890
+ });
891
+ }
892
+
893
+ /**
894
+ * The principal to grant permissions to.
895
+ */
896
+ public get grantPrincipal(): IPrincipal {
897
+ return this.agentCoreRuntime.grantPrincipal;
898
+ }
899
+
900
+ /**
901
+ * Network connections for this agent runtime.
902
+ */
903
+ public get connections(): Connections {
904
+ return this.agentCoreRuntime.connections;
905
+ }
906
+
907
+ /**
908
+ * The HTTPS invocation URL of the runtime.
909
+ */
910
+ public get invocationUrl(): string {
911
+ // The URL must URL-encode the runtime ARN (':' -> '%3A', '/' -> '%2F').
912
+ // The ARN is a CDK token, so encode at deploy time via Fn.join/Fn.split.
913
+ const encodedArn = Fn.join(
914
+ '%2F',
915
+ Fn.split(
916
+ '/',
917
+ Fn.join('%3A', Fn.split(':', this.agentCoreRuntime.agentRuntimeArn)),
918
+ ),
919
+ );
920
+ return \`https://bedrock-agentcore.\${Stack.of(this).region}.amazonaws.com/runtimes/\${encodedArn}/invocations?qualifier=DEFAULT\`;
921
+ }
922
+
923
+ /**
924
+ * Grants IAM permissions to invoke this agent runtime.
925
+ *
926
+ * @param grantee - The IAM principal to grant permissions to
927
+ */
928
+ public grantInvokeAccess(grantee: IGrantable) {
929
+ this.agentCoreRuntime.grantInvoke(grantee);
930
+
931
+ Grant.addToPrincipal({
932
+ grantee,
933
+ actions: ['bedrock-agentcore:InvokeAgentRuntimeWithWebSocketStream'],
934
+ resourceArns: [
935
+ this.agentCoreRuntime.agentRuntimeArn,
936
+ \`\${this.agentCoreRuntime.agentRuntimeArn}/*\`,
937
+ ],
938
+ });
939
+ }
940
+ }
941
+ "
942
+ `;