@aws/agentcore 1.0.0-preview.2 → 1.0.0-preview.20

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 (256) hide show
  1. package/README.md +193 -33
  2. package/dist/agent-inspector/index.css +1 -1
  3. package/dist/agent-inspector/index.js +99 -84
  4. package/dist/assets/__tests__/__snapshots__/assets.snapshot.test.ts.snap +3132 -366
  5. package/dist/assets/__tests__/__snapshots__/dockerfile-render.test.ts.snap +6 -2
  6. package/dist/assets/__tests__/assets.snapshot.test.ts +10 -24
  7. package/dist/assets/__tests__/googleadk-session-eviction.test.ts +87 -0
  8. package/dist/assets/__tests__/summarization-namespace.test.ts +43 -0
  9. package/dist/assets/agents/AGENTS.md +87 -11
  10. package/dist/assets/cdk/bin/cdk.ts +87 -26
  11. package/dist/assets/cdk/lib/cdk-stack.ts +185 -55
  12. package/dist/assets/cdk/package.json +1 -1
  13. package/dist/assets/cdk/test/cdk.test.ts +4 -0
  14. package/dist/assets/container/python/Dockerfile +7 -1
  15. package/dist/assets/container/typescript/Dockerfile +25 -0
  16. package/dist/assets/container/typescript/dockerignore.template +24 -0
  17. package/dist/assets/datasets/predefined-v1.jsonl +3 -0
  18. package/dist/assets/datasets/simulated-v1.jsonl +3 -0
  19. package/dist/assets/python/a2a/googleadk/base/main.py +24 -16
  20. package/dist/assets/python/a2a/googleadk/base/pyproject.toml +3 -3
  21. package/dist/assets/python/a2a/langchain_langgraph/base/main.py +24 -16
  22. package/dist/assets/python/a2a/langchain_langgraph/base/pyproject.toml +3 -2
  23. package/dist/assets/python/a2a/strands/base/main.py +23 -17
  24. package/dist/assets/python/a2a/strands/base/pyproject.toml +2 -2
  25. package/dist/assets/python/a2a/strands/capabilities/memory/session.py +10 -2
  26. package/dist/assets/python/agui/googleadk/base/main.py +62 -2
  27. package/dist/assets/python/agui/googleadk/base/pyproject.toml +3 -3
  28. package/dist/assets/python/agui/langchain_langgraph/base/main.py +56 -0
  29. package/dist/assets/python/agui/langchain_langgraph/base/pyproject.toml +2 -1
  30. package/dist/assets/python/agui/strands/base/main.py +63 -1
  31. package/dist/assets/python/agui/strands/base/pyproject.toml +1 -1
  32. package/dist/assets/python/agui/strands/capabilities/memory/session.py +10 -2
  33. package/dist/assets/python/http/autogen/base/main.py +60 -29
  34. package/dist/assets/python/http/autogen/base/pyproject.toml +1 -1
  35. package/dist/assets/python/http/googleadk/base/main.py +69 -24
  36. package/dist/assets/python/http/googleadk/base/mcp_client/client.py +7 -7
  37. package/dist/assets/python/http/googleadk/base/pyproject.toml +2 -1
  38. package/dist/assets/python/http/langchain_langgraph/base/main.py +115 -24
  39. package/dist/assets/python/http/langchain_langgraph/base/mcp_client/client.py +10 -8
  40. package/dist/assets/python/http/langchain_langgraph/base/pyproject.toml +3 -2
  41. package/dist/assets/python/http/openaiagents/base/main.py +61 -32
  42. package/dist/assets/python/http/openaiagents/base/mcp_client/client.py +4 -4
  43. package/dist/assets/python/http/openaiagents/base/pyproject.toml +2 -2
  44. package/dist/assets/python/http/strands/base/main.py +571 -47
  45. package/dist/assets/python/http/strands/base/mcp_client/client.py +49 -6
  46. package/dist/assets/python/http/strands/base/model/load.py +119 -3
  47. package/dist/assets/python/http/strands/base/model/mantle_compat.py +21 -0
  48. package/dist/assets/python/http/strands/base/pyproject.toml +9 -3
  49. package/dist/assets/python/http/strands/base/skills/fetcher.py +279 -0
  50. package/dist/assets/python/http/strands/capabilities/execution-limits/hooks/execution_limits.py +54 -0
  51. package/dist/assets/python/http/strands/capabilities/memory/session.py +10 -2
  52. package/dist/assets/python/http/strands/capabilities/payments/__init__.py +4 -0
  53. package/dist/assets/python/http/strands/capabilities/payments/payments.py +142 -0
  54. package/dist/assets/python/mcp/standalone/base/main.py +58 -0
  55. package/dist/assets/typescript/http/strands/base/README.md +37 -0
  56. package/dist/assets/typescript/http/strands/base/gitignore.template +22 -0
  57. package/dist/assets/typescript/http/strands/base/main.ts +144 -0
  58. package/dist/assets/typescript/http/strands/base/mcp_client/client.ts +11 -0
  59. package/dist/assets/typescript/http/strands/base/model/load.ts +102 -0
  60. package/dist/assets/typescript/http/strands/base/package.json +38 -0
  61. package/dist/assets/typescript/http/strands/base/tsconfig.json +19 -0
  62. package/dist/assets/typescript/http/strands/capabilities/memory/memory.ts +52 -0
  63. package/dist/assets/typescript/http/vercelai/base/README.md +37 -0
  64. package/dist/assets/typescript/http/vercelai/base/gitignore.template +22 -0
  65. package/dist/assets/typescript/http/vercelai/base/main.ts +64 -0
  66. package/dist/assets/typescript/http/vercelai/base/model/load.ts +121 -0
  67. package/dist/assets/typescript/http/vercelai/base/package.json +35 -0
  68. package/dist/assets/typescript/http/vercelai/base/tsconfig.json +19 -0
  69. package/dist/cli/index.mjs +1416 -568
  70. package/dist/lib/errors/index.d.ts +1 -1
  71. package/dist/lib/errors/index.d.ts.map +1 -1
  72. package/dist/lib/errors/index.js +1 -1
  73. package/dist/lib/errors/index.js.map +1 -1
  74. package/dist/lib/errors/types.d.ts +259 -0
  75. package/dist/lib/errors/types.d.ts.map +1 -0
  76. package/dist/lib/errors/types.js +402 -0
  77. package/dist/lib/errors/types.js.map +1 -0
  78. package/dist/lib/errors/zod.d.ts +8 -0
  79. package/dist/lib/errors/zod.d.ts.map +1 -0
  80. package/dist/lib/errors/{config.js → zod.js} +8 -81
  81. package/dist/lib/errors/zod.js.map +1 -0
  82. package/dist/lib/index.d.ts +3 -0
  83. package/dist/lib/index.d.ts.map +1 -1
  84. package/dist/lib/index.js +4 -1
  85. package/dist/lib/index.js.map +1 -1
  86. package/dist/lib/packaging/build-args.js +2 -2
  87. package/dist/lib/packaging/build-args.js.map +1 -1
  88. package/dist/lib/packaging/container.js +5 -5
  89. package/dist/lib/packaging/container.js.map +1 -1
  90. package/dist/lib/packaging/helpers.d.ts +16 -0
  91. package/dist/lib/packaging/helpers.d.ts.map +1 -1
  92. package/dist/lib/packaging/helpers.js +127 -29
  93. package/dist/lib/packaging/helpers.js.map +1 -1
  94. package/dist/lib/packaging/index.d.ts +0 -1
  95. package/dist/lib/packaging/index.d.ts.map +1 -1
  96. package/dist/lib/packaging/index.js +4 -19
  97. package/dist/lib/packaging/index.js.map +1 -1
  98. package/dist/lib/packaging/node.d.ts +2 -2
  99. package/dist/lib/packaging/node.d.ts.map +1 -1
  100. package/dist/lib/packaging/node.js +83 -38
  101. package/dist/lib/packaging/node.js.map +1 -1
  102. package/dist/lib/packaging/python.js +12 -12
  103. package/dist/lib/packaging/python.js.map +1 -1
  104. package/dist/lib/result.d.ts +50 -0
  105. package/dist/lib/result.d.ts.map +1 -0
  106. package/dist/lib/result.js +49 -0
  107. package/dist/lib/result.js.map +1 -0
  108. package/dist/lib/schemas/io/config-io.d.ts +8 -0
  109. package/dist/lib/schemas/io/config-io.d.ts.map +1 -1
  110. package/dist/lib/schemas/io/config-io.js +21 -3
  111. package/dist/lib/schemas/io/config-io.js.map +1 -1
  112. package/dist/lib/schemas/io/global-config.d.ts +40 -0
  113. package/dist/lib/schemas/io/global-config.d.ts.map +1 -0
  114. package/dist/lib/schemas/io/global-config.js +118 -0
  115. package/dist/lib/schemas/io/global-config.js.map +1 -0
  116. package/dist/lib/schemas/io/index.d.ts +1 -2
  117. package/dist/lib/schemas/io/index.d.ts.map +1 -1
  118. package/dist/lib/schemas/io/index.js +1 -4
  119. package/dist/lib/schemas/io/index.js.map +1 -1
  120. package/dist/lib/schemas/io/path-resolver.d.ts +0 -6
  121. package/dist/lib/schemas/io/path-resolver.d.ts.map +1 -1
  122. package/dist/lib/schemas/io/path-resolver.js +3 -13
  123. package/dist/lib/schemas/io/path-resolver.js.map +1 -1
  124. package/dist/lib/secrets/cipher.d.ts +12 -0
  125. package/dist/lib/secrets/cipher.d.ts.map +1 -0
  126. package/dist/lib/secrets/cipher.js +54 -0
  127. package/dist/lib/secrets/cipher.js.map +1 -0
  128. package/dist/lib/secrets/index.d.ts +4 -0
  129. package/dist/lib/secrets/index.d.ts.map +1 -0
  130. package/dist/lib/secrets/index.js +15 -0
  131. package/dist/lib/secrets/index.js.map +1 -0
  132. package/dist/lib/secrets/key-provider.d.ts +16 -0
  133. package/dist/lib/secrets/key-provider.d.ts.map +1 -0
  134. package/dist/lib/secrets/key-provider.js +191 -0
  135. package/dist/lib/secrets/key-provider.js.map +1 -0
  136. package/dist/lib/secrets/sensitive-keys.d.ts +21 -0
  137. package/dist/lib/secrets/sensitive-keys.d.ts.map +1 -0
  138. package/dist/lib/secrets/sensitive-keys.js +67 -0
  139. package/dist/lib/secrets/sensitive-keys.js.map +1 -0
  140. package/dist/lib/time-constants.d.ts +5 -0
  141. package/dist/lib/time-constants.d.ts.map +1 -0
  142. package/dist/lib/time-constants.js +8 -0
  143. package/dist/lib/time-constants.js.map +1 -0
  144. package/dist/lib/utils/env.d.ts +8 -2
  145. package/dist/lib/utils/env.d.ts.map +1 -1
  146. package/dist/lib/utils/env.js +65 -17
  147. package/dist/lib/utils/env.js.map +1 -1
  148. package/dist/lib/utils/index.d.ts +3 -2
  149. package/dist/lib/utils/index.d.ts.map +1 -1
  150. package/dist/lib/utils/index.js +6 -1
  151. package/dist/lib/utils/index.js.map +1 -1
  152. package/dist/lib/utils/polling.d.ts +31 -0
  153. package/dist/lib/utils/polling.d.ts.map +1 -0
  154. package/dist/lib/utils/polling.js +61 -0
  155. package/dist/lib/utils/polling.js.map +1 -0
  156. package/dist/lib/utils/zod.d.ts +16 -0
  157. package/dist/lib/utils/zod.d.ts.map +1 -1
  158. package/dist/lib/utils/zod.js +45 -0
  159. package/dist/lib/utils/zod.js.map +1 -1
  160. package/dist/schema/constants.d.ts +56 -2
  161. package/dist/schema/constants.d.ts.map +1 -1
  162. package/dist/schema/constants.js +82 -7
  163. package/dist/schema/constants.js.map +1 -1
  164. package/dist/schema/schemas/agent-env.d.ts +156 -6
  165. package/dist/schema/schemas/agent-env.d.ts.map +1 -1
  166. package/dist/schema/schemas/agent-env.js +186 -13
  167. package/dist/schema/schemas/agent-env.js.map +1 -1
  168. package/dist/schema/schemas/agentcore-project.d.ts +446 -11
  169. package/dist/schema/schemas/agentcore-project.d.ts.map +1 -1
  170. package/dist/schema/schemas/agentcore-project.js +283 -18
  171. package/dist/schema/schemas/agentcore-project.js.map +1 -1
  172. package/dist/schema/schemas/auth.d.ts +174 -0
  173. package/dist/schema/schemas/auth.d.ts.map +1 -1
  174. package/dist/schema/schemas/auth.js +127 -3
  175. package/dist/schema/schemas/auth.js.map +1 -1
  176. package/dist/schema/schemas/connections.d.ts +185 -0
  177. package/dist/schema/schemas/connections.d.ts.map +1 -0
  178. package/dist/schema/schemas/connections.js +176 -0
  179. package/dist/schema/schemas/connections.js.map +1 -0
  180. package/dist/schema/schemas/deployed-state.d.ts +361 -5
  181. package/dist/schema/schemas/deployed-state.d.ts.map +1 -1
  182. package/dist/schema/schemas/deployed-state.js +105 -2
  183. package/dist/schema/schemas/deployed-state.js.map +1 -1
  184. package/dist/schema/schemas/index.d.ts +1 -0
  185. package/dist/schema/schemas/index.d.ts.map +1 -1
  186. package/dist/schema/schemas/index.js +1 -0
  187. package/dist/schema/schemas/index.js.map +1 -1
  188. package/dist/schema/schemas/mcp-defs.d.ts +2 -1
  189. package/dist/schema/schemas/mcp-defs.d.ts.map +1 -1
  190. package/dist/schema/schemas/mcp-defs.js +3 -2
  191. package/dist/schema/schemas/mcp-defs.js.map +1 -1
  192. package/dist/schema/schemas/mcp.d.ts +197 -0
  193. package/dist/schema/schemas/mcp.d.ts.map +1 -1
  194. package/dist/schema/schemas/mcp.js +342 -6
  195. package/dist/schema/schemas/mcp.js.map +1 -1
  196. package/dist/schema/schemas/primitives/ab-test.d.ts +135 -0
  197. package/dist/schema/schemas/primitives/ab-test.d.ts.map +1 -0
  198. package/dist/schema/schemas/primitives/ab-test.js +95 -0
  199. package/dist/schema/schemas/primitives/ab-test.js.map +1 -0
  200. package/dist/schema/schemas/primitives/config-bundle.d.ts +32 -0
  201. package/dist/schema/schemas/primitives/config-bundle.d.ts.map +1 -0
  202. package/dist/schema/schemas/primitives/config-bundle.js +41 -0
  203. package/dist/schema/schemas/primitives/config-bundle.js.map +1 -0
  204. package/dist/schema/schemas/primitives/dataset.d.ts +48 -0
  205. package/dist/schema/schemas/primitives/dataset.d.ts.map +1 -0
  206. package/dist/schema/schemas/primitives/dataset.js +58 -0
  207. package/dist/schema/schemas/primitives/dataset.js.map +1 -0
  208. package/dist/schema/schemas/primitives/evaluator.d.ts +8 -0
  209. package/dist/schema/schemas/primitives/evaluator.d.ts.map +1 -1
  210. package/dist/schema/schemas/primitives/evaluator.js +17 -1
  211. package/dist/schema/schemas/primitives/evaluator.js.map +1 -1
  212. package/dist/schema/schemas/primitives/harness.d.ts +377 -19
  213. package/dist/schema/schemas/primitives/harness.d.ts.map +1 -1
  214. package/dist/schema/schemas/primitives/harness.js +379 -24
  215. package/dist/schema/schemas/primitives/harness.js.map +1 -1
  216. package/dist/schema/schemas/primitives/index.d.ts +13 -7
  217. package/dist/schema/schemas/primitives/index.d.ts.map +1 -1
  218. package/dist/schema/schemas/primitives/index.js +37 -1
  219. package/dist/schema/schemas/primitives/index.js.map +1 -1
  220. package/dist/schema/schemas/primitives/knowledge-base.d.ts +104 -0
  221. package/dist/schema/schemas/primitives/knowledge-base.d.ts.map +1 -0
  222. package/dist/schema/schemas/primitives/knowledge-base.js +99 -0
  223. package/dist/schema/schemas/primitives/knowledge-base.js.map +1 -0
  224. package/dist/schema/schemas/primitives/memory.d.ts +22 -4
  225. package/dist/schema/schemas/primitives/memory.d.ts.map +1 -1
  226. package/dist/schema/schemas/primitives/memory.js +57 -16
  227. package/dist/schema/schemas/primitives/memory.js.map +1 -1
  228. package/dist/schema/schemas/primitives/online-eval-config.d.ts +21 -2
  229. package/dist/schema/schemas/primitives/online-eval-config.d.ts.map +1 -1
  230. package/dist/schema/schemas/primitives/online-eval-config.js +45 -5
  231. package/dist/schema/schemas/primitives/online-eval-config.js.map +1 -1
  232. package/dist/schema/schemas/primitives/payment.d.ts +54 -0
  233. package/dist/schema/schemas/primitives/payment.d.ts.map +1 -0
  234. package/dist/schema/schemas/primitives/payment.js +79 -0
  235. package/dist/schema/schemas/primitives/payment.js.map +1 -0
  236. package/dist/schema/schemas/primitives/policy.d.ts +26 -0
  237. package/dist/schema/schemas/primitives/policy.d.ts.map +1 -1
  238. package/dist/schema/schemas/primitives/policy.js +5 -1
  239. package/dist/schema/schemas/primitives/policy.js.map +1 -1
  240. package/npm-shrinkwrap.json +17013 -0
  241. package/package.json +43 -21
  242. package/scripts/bump-version.ts +4 -4
  243. package/scripts/bundle.mjs +70 -41
  244. package/scripts/run-e2e-dev.sh +56 -0
  245. package/scripts/run-e2e-local.sh +145 -0
  246. package/dist/lib/errors/config.d.ts +0 -49
  247. package/dist/lib/errors/config.d.ts.map +0 -1
  248. package/dist/lib/errors/config.js.map +0 -1
  249. package/dist/lib/packaging/errors.d.ts +0 -16
  250. package/dist/lib/packaging/errors.d.ts.map +0 -1
  251. package/dist/lib/packaging/errors.js +0 -36
  252. package/dist/lib/packaging/errors.js.map +0 -1
  253. package/dist/lib/schemas/io/cli-config.d.ts +0 -12
  254. package/dist/lib/schemas/io/cli-config.d.ts.map +0 -1
  255. package/dist/lib/schemas/io/cli-config.js +0 -35
  256. package/dist/lib/schemas/io/cli-config.js.map +0 -1
@@ -1,26 +1,39 @@
1
1
  import {
2
2
  AgentCoreApplication,
3
3
  AgentCoreMcp,
4
+ AgentCorePaymentManager,
5
+ AgentCorePaymentConnector,
4
6
  type AgentCoreProjectSpec,
5
7
  type AgentCoreMcpSpec,
6
- ContainerSourceAssetFromPath,
7
- AgentEcrRepository,
8
- ContainerBuildProject,
9
- ContainerImageBuilder,
8
+ type CustomJWTAuthorizerConfig,
9
+ type HarnessDeploymentConfig,
10
10
  } from '@aws/agentcore-cdk';
11
11
  import { CfnOutput, Stack, type StackProps } from 'aws-cdk-lib';
12
+ import * as iam from 'aws-cdk-lib/aws-iam';
12
13
  import { Construct } from 'constructs';
13
14
 
14
- export interface HarnessConfig {
15
+ /**
16
+ * Harness deployment config: role-scoped fields (for IAM role + container build)
17
+ * plus the full validated spec + its config directory so the L3 construct can
18
+ * synthesize the AWS::BedrockAgentCore::Harness resource.
19
+ */
20
+ export type HarnessConfig = HarnessDeploymentConfig;
21
+
22
+ export interface PaymentConnectorSpec {
23
+ name: string;
24
+ provider: 'CoinbaseCDP' | 'StripePrivy';
25
+ credentialProviderArn: string;
26
+ }
27
+
28
+ export interface PaymentSpec {
15
29
  name: string;
16
- executionRoleArn?: string;
17
- memoryName?: string;
18
- containerUri?: string;
19
- hasDockerfile?: boolean;
20
- dockerfileName?: string;
21
- harnessDir?: string;
22
- tools?: { type: string; name: string }[];
23
- apiKeyArn?: string;
30
+ description?: string;
31
+ authorizerType: 'AWS_IAM' | 'CUSTOM_JWT';
32
+ authorizerConfiguration?: { customJWTAuthorizer: CustomJWTAuthorizerConfig };
33
+ autoPayment?: boolean;
34
+ paymentToolAllowlist?: string[];
35
+ networkPreferences?: string[];
36
+ connectors: PaymentConnectorSpec[];
24
37
  }
25
38
 
26
39
  export interface AgentCoreStackProps extends StackProps {
@@ -37,9 +50,38 @@ export interface AgentCoreStackProps extends StackProps {
37
50
  */
38
51
  credentials?: Record<string, { credentialProviderArn: string; clientSecretArn?: string }>;
39
52
  /**
40
- * Harness role configurations. Each entry creates an IAM execution role for a harness.
53
+ * Harness role configurations.
41
54
  */
42
55
  harnesses?: HarnessConfig[];
56
+ /**
57
+ * Parsed connectorParameters for non-S3 KB data sources, keyed by
58
+ * connectorConfigFile path. Forwarded to AgentCoreApplication.
59
+ */
60
+ connectorParametersByFile?: Record<string, Record<string, unknown>>;
61
+ /**
62
+ * Payment specifications with resolved credential provider ARNs.
63
+ */
64
+ paymentSpec?: PaymentSpec[];
65
+ }
66
+
67
+ function toCdkId(name: string): string {
68
+ return name.replace(/_/g, '');
69
+ }
70
+
71
+ /**
72
+ * Decide whether a deployed runtime should receive payment env vars + IAM grants.
73
+ * Payments today only ships a runtime shim for Python HTTP runtimes; injecting
74
+ * AGENTCORE_PAYMENT_* env vars into TypeScript / MCP / A2A / AGUI runtimes
75
+ * would surface env vars they cannot consume and would dilute least-privilege
76
+ * IAM grants for runtimes that never call ProcessPayment.
77
+ */
78
+ function isPaymentEligibleAgent(agent: { entrypoint?: string; protocol?: string }): boolean {
79
+ if (agent.protocol && agent.protocol !== 'HTTP') {
80
+ return false;
81
+ }
82
+ const entrypoint = typeof agent.entrypoint === 'string' ? agent.entrypoint : '';
83
+ const entrypointFile = entrypoint.split(':')[0] ?? '';
84
+ return entrypointFile.endsWith('.py');
43
85
  }
44
86
 
45
87
  /**
@@ -55,49 +97,21 @@ export class AgentCoreStack extends Stack {
55
97
  constructor(scope: Construct, id: string, props: AgentCoreStackProps) {
56
98
  super(scope, id, props);
57
99
 
58
- const { spec, mcpSpec, credentials, harnesses } = props;
59
-
60
- // Build container images for harnesses that specify a dockerfile (no containerUri).
61
- // Produces CDK outputs consumed by the imperative harness deployer.
62
- const harnessesForCdk = harnesses ? [...harnesses] : [];
63
- if (harnesses) {
64
- for (let i = 0; i < harnesses.length; i++) {
65
- const h = harnesses[i]!;
66
- if (h.hasDockerfile && !h.containerUri && h.harnessDir) {
67
- const pascalName = h.name.replace(/(^|_)([a-z])/g, (_: string, __: string, c: string) => c.toUpperCase());
68
- const sourceAsset = new ContainerSourceAssetFromPath(this, `Harness${pascalName}SourceAsset`, {
69
- sourcePath: h.harnessDir,
70
- });
71
- const ecrRepo = new AgentEcrRepository(this, `Harness${pascalName}EcrRepo`, {
72
- projectName: spec.name,
73
- agentName: `harness-${h.name}`,
74
- });
75
- const buildProject = ContainerBuildProject.getOrCreate(this);
76
- buildProject.grantPushTo(ecrRepo.repository);
77
- sourceAsset.asset.grantRead(buildProject.role);
78
-
79
- const builder = new ContainerImageBuilder(this, `Harness${pascalName}ContainerBuild`, {
80
- buildProject,
81
- sourceAsset,
82
- repository: ecrRepo,
83
- dockerfile: h.dockerfileName ?? 'Dockerfile',
84
- });
85
-
86
- new CfnOutput(this, `Harness${pascalName}ContainerUriOutput`, {
87
- value: builder.containerUri,
88
- });
89
-
90
- // Pass the built containerUri to the harness role construct so it gets ECR pull permissions
91
- harnessesForCdk[i] = { ...h, containerUri: builder.containerUri };
92
- }
93
- }
94
- }
100
+ const { spec, mcpSpec, credentials, harnesses, connectorParametersByFile, paymentSpec } = props;
95
101
 
96
102
  // Create AgentCoreApplication with all agents and harness roles
97
- this.application = new AgentCoreApplication(this, 'Application', {
98
- spec,
99
- harnesses: harnessesForCdk.length > 0 ? harnessesForCdk : undefined,
100
- });
103
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
104
+ const appProps: Record<string, unknown> = { spec };
105
+ if (harnesses?.length) {
106
+ appProps.harnesses = harnesses;
107
+ }
108
+ if (connectorParametersByFile && Object.keys(connectorParametersByFile).length > 0) {
109
+ appProps.connectorParametersByFile = connectorParametersByFile;
110
+ }
111
+ if (credentials) {
112
+ appProps.credentials = credentials;
113
+ }
114
+ this.application = new AgentCoreApplication(this, 'Application', appProps as any);
101
115
 
102
116
  // Create AgentCoreMcp if there are gateways configured
103
117
  if (mcpSpec?.agentCoreGateways && mcpSpec.agentCoreGateways.length > 0) {
@@ -110,6 +124,122 @@ export class AgentCoreStack extends Stack {
110
124
  });
111
125
  }
112
126
 
127
+ // Create payment infrastructure via CFN constructs
128
+ if (paymentSpec && paymentSpec.length > 0) {
129
+ for (const payment of paymentSpec) {
130
+ const mgrId = toCdkId(payment.name);
131
+ const manager = new AgentCorePaymentManager(this, `Payment${mgrId}`, {
132
+ projectName: spec.name,
133
+ name: payment.name,
134
+ authorizerType: payment.authorizerType,
135
+ description: payment.description,
136
+ authorizerConfiguration: payment.authorizerConfiguration,
137
+ tags: spec.tags,
138
+ });
139
+
140
+ const prefix = `AGENTCORE_PAYMENT_${payment.name.toUpperCase().replace(/-/g, '_')}`;
141
+
142
+ // Wire env vars from construct output tokens into eligible agent environments only.
143
+ // See isPaymentEligibleAgent — non-Python or non-HTTP runtimes have no shim that
144
+ // can consume these env vars, and giving them sts:AssumeRole on the
145
+ // ProcessPaymentRole would broaden the privilege surface unnecessarily.
146
+ for (const env of this.application.environments.values()) {
147
+ if (!isPaymentEligibleAgent(env.agent)) {
148
+ continue;
149
+ }
150
+ env.runtime.addEnvironmentVariable(`${prefix}_MANAGER_ARN`, manager.paymentManagerArn);
151
+ env.runtime.addEnvironmentVariable(`${prefix}_PROCESS_PAYMENT_ROLE_ARN`, manager.processPaymentRoleArn);
152
+
153
+ // Grant runtime execution role permission to assume the ProcessPaymentRole.
154
+ // The ProcessPaymentRole's trust policy allows AccountRootPrincipal, but the
155
+ // caller still needs sts:AssumeRole on its own role to perform the assumption.
156
+ env.runtime.role.addToPrincipalPolicy(
157
+ new iam.PolicyStatement({
158
+ actions: ['sts:AssumeRole'],
159
+ resources: [manager.processPaymentRoleArn],
160
+ })
161
+ );
162
+
163
+ // Grant payment data-plane actions directly to the runtime role.
164
+ //
165
+ // NOTE: This deviates from the canonical role model in the AgentCore Payments
166
+ // beta guide, which assigns Get/List/Create instrument+session actions to a
167
+ // separate ManagementRole and limits the agent's role to ProcessPayment only.
168
+ // The current SDK plugin (AgentCorePaymentsPlugin.generate_payment_header)
169
+ // calls GetPaymentInstrument internally during the 402 auto-pay path, so the
170
+ // runtime role needs read access. CreatePaymentSession is included so
171
+ // `agentcore invoke --auto-session` works without a separate ManagementRole
172
+ // call. Tighten this if the SDK is updated to accept pre-fetched instrument
173
+ // details and split create-session into a backend-only flow.
174
+ env.runtime.role.addToPrincipalPolicy(
175
+ new iam.PolicyStatement({
176
+ actions: [
177
+ 'bedrock-agentcore:GetPaymentInstrument',
178
+ 'bedrock-agentcore:ListPaymentInstruments',
179
+ 'bedrock-agentcore:GetPaymentInstrumentBalance',
180
+ 'bedrock-agentcore:GetPaymentSession',
181
+ 'bedrock-agentcore:ListPaymentSessions',
182
+ 'bedrock-agentcore:CreatePaymentSession',
183
+ 'bedrock-agentcore:ProcessPayment',
184
+ ],
185
+ resources: [manager.paymentManagerArn, `${manager.paymentManagerArn}/*`],
186
+ })
187
+ );
188
+
189
+ if (payment.autoPayment !== undefined) {
190
+ env.runtime.addEnvironmentVariable(`${prefix}_AUTO_PAYMENT`, String(payment.autoPayment));
191
+ }
192
+ if (payment.paymentToolAllowlist) {
193
+ env.runtime.addEnvironmentVariable(`${prefix}_TOOL_ALLOWLIST`, payment.paymentToolAllowlist.join(','));
194
+ }
195
+ if (payment.networkPreferences) {
196
+ env.runtime.addEnvironmentVariable(`${prefix}_NETWORK_PREFERENCES`, payment.networkPreferences.join(','));
197
+ }
198
+ if (payment.authorizerType === 'CUSTOM_JWT') {
199
+ env.runtime.addEnvironmentVariable(`${prefix}_AUTH_MODE`, 'bearer');
200
+ }
201
+ }
202
+
203
+ // Create connectors for this manager
204
+ for (const connector of payment.connectors) {
205
+ const connId = toCdkId(connector.name);
206
+ const conn = new AgentCorePaymentConnector(this, `Payment${mgrId}${connId}`, {
207
+ projectName: spec.name,
208
+ paymentManager: manager,
209
+ connectorName: connector.name,
210
+ connectorType: connector.provider,
211
+ credentialProviderArn: connector.credentialProviderArn,
212
+ });
213
+
214
+ // Wire first connector's ID as env var (eligible agents only)
215
+ if (connector === payment.connectors[0]) {
216
+ for (const env of this.application.environments.values()) {
217
+ if (!isPaymentEligibleAgent(env.agent)) continue;
218
+ env.runtime.addEnvironmentVariable(`${prefix}_CONNECTOR_ID`, conn.paymentConnectorId);
219
+ }
220
+ }
221
+
222
+ new CfnOutput(this, `Payment${mgrId}${connId}ConnectorId`, {
223
+ value: conn.paymentConnectorId,
224
+ });
225
+ }
226
+
227
+ // CFN Outputs for post-deploy state parsing
228
+ new CfnOutput(this, `Payment${mgrId}ManagerArn`, {
229
+ value: manager.paymentManagerArn,
230
+ });
231
+ new CfnOutput(this, `Payment${mgrId}ManagerId`, {
232
+ value: manager.paymentManagerId,
233
+ });
234
+ new CfnOutput(this, `Payment${mgrId}ProcessPaymentRoleArn`, {
235
+ value: manager.processPaymentRoleArn,
236
+ });
237
+ new CfnOutput(this, `Payment${mgrId}ResourceRetrievalRoleArn`, {
238
+ value: manager.resourceRetrievalRoleArn,
239
+ });
240
+ }
241
+ }
242
+
113
243
  // Stack-level output
114
244
  new CfnOutput(this, 'StackNameOutput', {
115
245
  description: 'Name of the CloudFormation Stack',
@@ -18,7 +18,7 @@
18
18
  "@types/node": "^24.10.1",
19
19
  "jest": "^29.7.0",
20
20
  "ts-jest": "^29.2.5",
21
- "aws-cdk": "2.1100.1",
21
+ "aws-cdk": "2.1126.0",
22
22
  "prettier": "^3.4.2",
23
23
  "typescript": "~5.9.3"
24
24
  },
@@ -14,10 +14,14 @@ test('AgentCoreStack synthesizes with empty spec', () => {
14
14
  credentials: [],
15
15
  evaluators: [],
16
16
  onlineEvalConfigs: [],
17
+ configBundles: [],
17
18
  policyEngines: [],
19
+ payments: [],
18
20
  agentCoreGateways: [],
19
21
  mcpRuntimeTools: [],
20
22
  unassignedTargets: [],
23
+ datasets: [],
24
+ knowledgeBases: [],
21
25
  },
22
26
  });
23
27
  const template = Template.fromStack(stack);
@@ -1,4 +1,10 @@
1
- FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim
1
+ FROM public.ecr.aws/docker/library/python:3.12-slim-trixie
2
+
3
+ {{#if gitSkills}}
4
+ RUN apt-get update && apt-get install -y --no-install-recommends git && rm -rf /var/lib/apt/lists/*
5
+
6
+ {{/if}}
7
+ RUN pip install --no-cache-dir uv
2
8
 
3
9
  ARG UV_DEFAULT_INDEX
4
10
  ARG UV_INDEX
@@ -0,0 +1,25 @@
1
+ FROM public.ecr.aws/docker/library/node:22-slim
2
+
3
+ WORKDIR /app
4
+
5
+ ENV NODE_ENV=production \
6
+ DOCKER_CONTAINER=1
7
+
8
+ RUN userdel -r node 2>/dev/null || true
9
+ RUN useradd -m -u 1000 bedrock_agentcore
10
+
11
+ COPY package.json package-lock.json* ./
12
+ RUN npm ci --omit=dev || npm install --omit=dev
13
+
14
+ COPY --chown=bedrock_agentcore:bedrock_agentcore . .
15
+
16
+ USER bedrock_agentcore
17
+
18
+ # AgentCore Runtime service contract ports
19
+ # https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-service-contract.html
20
+ # 8080: HTTP Mode
21
+ # 8000: MCP Mode
22
+ # 9000: A2A Mode
23
+ EXPOSE 8080 8000 9000
24
+
25
+ CMD ["npx", "tsx", "main.ts"]
@@ -0,0 +1,24 @@
1
+ # Node
2
+ node_modules/
3
+ dist/
4
+ npm-debug.log*
5
+ yarn-debug.log*
6
+ yarn-error.log*
7
+
8
+ # IDE
9
+ .vscode/
10
+ .idea/
11
+
12
+ # Testing
13
+ coverage/
14
+
15
+ # Secrets and environment files
16
+ .env
17
+ .env.*
18
+
19
+ # Version control
20
+ .git/
21
+
22
+ # AgentCore build artifacts
23
+ .agentcore/artifacts/
24
+ *.zip
@@ -0,0 +1,3 @@
1
+ {"scenario_id": "refund-policy", "turns": [{"input": "What is your refund policy?", "expectedResponse": "We offer full refunds within 30 days of purchase. After 30 days, we can provide store credit."}, {"input": "What if I lost my receipt?", "expectedResponse": "No problem! We can look up your purchase using your email address or payment method."}], "assertions": ["Agent should clearly state the 30-day refund window", "Agent should offer alternatives for lost receipts"], "expected_trajectory": ["lookup_policy", "check_eligibility"]}
2
+ {"scenario_id": "order-tracking", "turns": [{"input": "Where is my order #12345?", "expectedResponse": "Let me look up order #12345 for you. I can see it shipped on Monday and is expected to arrive by Thursday."}], "assertions": ["Agent should reference the specific order number", "Agent should provide estimated delivery date"], "expected_trajectory": ["lookup_order", "get_shipping_status"]}
3
+ {"scenario_id": "account-locked", "turns": [{"input": "I can't log into my account", "expectedResponse": "I'm sorry you're having trouble logging in. Let me help you regain access. Can you provide the email address associated with your account?"}, {"input": "It's john@example.com", "expectedResponse": "I've sent a password reset link to john@example.com. Please check your inbox and spam folder. The link expires in 24 hours."}], "assertions": ["Agent should ask for identifying information", "Agent should explain the reset process clearly"], "expected_trajectory": ["verify_identity", "send_reset_link"]}
@@ -0,0 +1,3 @@
1
+ {"scenario_id": "frustrated-refund-customer", "input": "I want a refund for my cancelled flight BK-98765", "actor_profile": {"traits": {"personality": "impatient and frustrated", "communication_style": "direct and demanding"}, "context": "Has been waiting 3 days for a refund with no response. Previously had a bad experience with customer service.", "goal": "Get a full cash refund for cancelled flight BK-98765, not a voucher or credit"}, "max_turns": 10, "assertions": ["Agent should acknowledge the frustration", "Agent should not offer only vouchers when cash refund is requested", "Agent should provide a timeline for the refund"]}
2
+ {"scenario_id": "confused-new-user", "input": "How do I set up my new account?", "actor_profile": {"traits": {"personality": "polite but confused", "communication_style": "asks many follow-up questions", "technical_level": "beginner"}, "context": "First time using the service. Not familiar with technical terminology. English is a second language.", "goal": "Successfully create and configure a new account with basic settings"}, "max_turns": 15, "assertions": ["Agent should use simple non-technical language", "Agent should break instructions into small steps", "Agent should confirm understanding at each step"]}
3
+ {"scenario_id": "edge-case-multi-issue", "input": "I need to change my flight AND get a refund for the hotel that was bundled with it", "actor_profile": {"traits": {"personality": "methodical and detail-oriented", "communication_style": "provides lots of context upfront"}, "context": "Has a bundled flight+hotel booking. Flight was changed by the airline, making the hotel dates wrong. Wants partial refund for hotel and rebooking for flight.", "goal": "Get the flight rebooked to new dates AND get a refund for the hotel nights that no longer align"}, "max_turns": 12, "assertions": ["Agent should handle both issues without losing track", "Agent should clarify which parts are refundable", "Agent should not close the conversation until both issues are resolved"]}
@@ -1,4 +1,6 @@
1
+ {{#if needsOs}}
1
2
  import os
3
+ {{/if}}
2
4
  from google.adk.agents import Agent
3
5
  from google.adk.a2a.executor.a2a_agent_executor import A2aAgentExecutor
4
6
  from google.adk.runners import Runner
@@ -17,18 +19,21 @@ def add_numbers(a: int, b: int) -> int:
17
19
 
18
20
  tools = [add_numbers]
19
21
 
20
- {{#if sessionStorageMountPath}}
21
- SESSION_STORAGE_PATH = "{{sessionStorageMountPath}}"
22
+ {{#if needsOs}}
23
+ _MOUNT_PATHS = [
24
+ {{#if sessionStorageMountPath}}"{{sessionStorageMountPath}}",{{/if}}
25
+ {{#each efsMounts}}"{{mountPath}}",{{/each}}
26
+ {{#each s3Mounts}}"{{mountPath}}",{{/each}}
27
+ ]
22
28
 
23
29
  def _safe_resolve(path: str) -> str:
24
- """Resolve path safely within the storage boundary."""
25
- resolved = os.path.realpath(os.path.join(SESSION_STORAGE_PATH, path.lstrip("/")))
26
- if not resolved.startswith(os.path.realpath(SESSION_STORAGE_PATH)):
27
- raise ValueError(f"Path '{path}' is outside the storage boundary")
30
+ resolved = os.path.realpath(path)
31
+ if not any(resolved == os.path.realpath(m) or resolved.startswith(os.path.realpath(m) + os.sep) for m in _MOUNT_PATHS):
32
+ raise ValueError(f"Path '{path}' is not within any configured mount ({', '.join(_MOUNT_PATHS)})")
28
33
  return resolved
29
34
 
30
35
  def file_read(path: str) -> str:
31
- """Read a file from persistent storage. The path is relative to the storage root."""
36
+ """Read a file from a mounted filesystem. Use the absolute path (e.g. /mnt/tools/data.txt)."""
32
37
  try:
33
38
  full_path = _safe_resolve(path)
34
39
  with open(full_path) as f:
@@ -39,7 +44,7 @@ def file_read(path: str) -> str:
39
44
  return f"Error reading '{path}': {e.strerror}"
40
45
 
41
46
  def file_write(path: str, content: str) -> str:
42
- """Write content to a file in persistent storage. The path is relative to the storage root."""
47
+ """Write a file to a mounted filesystem. Use the absolute path (e.g. /mnt/tools/data.txt)."""
43
48
  try:
44
49
  full_path = _safe_resolve(path)
45
50
  parent = os.path.dirname(full_path)
@@ -53,25 +58,28 @@ def file_write(path: str, content: str) -> str:
53
58
  except OSError as e:
54
59
  return f"Error writing '{path}': {e.strerror}"
55
60
 
56
- def list_files(directory: str = "") -> str:
57
- """List files in persistent storage. The directory is relative to the storage root."""
61
+ def list_files(path: str) -> str:
62
+ """List files in a mounted filesystem directory. Use the absolute path (e.g. /mnt/tools)."""
58
63
  try:
59
- target = _safe_resolve(directory)
60
- entries = os.listdir(target)
64
+ full_path = _safe_resolve(path)
65
+ entries = os.listdir(full_path)
61
66
  return "\n".join(entries) if entries else "(empty directory)"
62
67
  except ValueError as e:
63
68
  return str(e)
64
69
  except OSError as e:
65
- return f"Error listing '{directory}': {e.strerror}"
70
+ return f"Error listing '{path}': {e.strerror}"
66
71
 
67
72
  tools.extend([file_read, file_write, list_files])
68
73
  {{/if}}
69
74
 
70
75
  AGENT_INSTRUCTION = """
71
76
  You are a helpful assistant. Use tools when appropriate.
72
- {{#if sessionStorageMountPath}}
73
- You have persistent storage at {{sessionStorageMountPath}}. Use file tools to read and write files. Data persists across sessions.
74
- {{/if}}
77
+ {{#if needsOs}}
78
+ You have access to the following mounted filesystems. Use file_read, file_write, and list_files with full absolute paths:
79
+ {{#if sessionStorageMountPath}}- {{sessionStorageMountPath}}: ephemeral session storage (lost when session ends)
80
+ {{/if}}{{#each efsMounts}}- {{mountPath}}: EFS persistent storage (persists across sessions and agent restarts)
81
+ {{/each}}{{#each s3Mounts}}- {{mountPath}}: S3 Files persistent storage (durable, backed by S3)
82
+ {{/each}}{{/if}}
75
83
  """
76
84
 
77
85
  agent = Agent(
@@ -9,11 +9,11 @@ description = "AgentCore A2A Agent using Google ADK"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
11
11
  dependencies = [
12
- "a2a-sdk >= 0.2.0",
12
+ "a2a-sdk >= 0.2.0, < 1.0.0",
13
13
  "aws-opentelemetry-distro",
14
14
  "bedrock-agentcore[a2a] >= 1.0.3",
15
- "google-adk >= 1.0.0",
16
- "google-genai >= 1.0.0",
15
+ "google-adk >= 1.0.0, < 2.0.0",
16
+ "google-genai >= 1.0.0, < 2.0.0",
17
17
  ]
18
18
 
19
19
  [tool.hatch.build.targets.wheel]
@@ -1,4 +1,6 @@
1
+ {{#if needsOs}}
1
2
  import os
3
+ {{/if}}
2
4
  from langchain_core.tools import tool
3
5
  from langgraph.prebuilt import create_react_agent
4
6
  from opentelemetry.instrumentation.langchain import LangchainInstrumentor
@@ -21,19 +23,22 @@ def add_numbers(a: int, b: int) -> int:
21
23
 
22
24
  tools = [add_numbers]
23
25
 
24
- {{#if sessionStorageMountPath}}
25
- SESSION_STORAGE_PATH = "{{sessionStorageMountPath}}"
26
+ {{#if needsOs}}
27
+ _MOUNT_PATHS = [
28
+ {{#if sessionStorageMountPath}}"{{sessionStorageMountPath}}",{{/if}}
29
+ {{#each efsMounts}}"{{mountPath}}",{{/each}}
30
+ {{#each s3Mounts}}"{{mountPath}}",{{/each}}
31
+ ]
26
32
 
27
33
  def _safe_resolve(path: str) -> str:
28
- """Resolve path safely within the storage boundary."""
29
- resolved = os.path.realpath(os.path.join(SESSION_STORAGE_PATH, path.lstrip("/")))
30
- if not resolved.startswith(os.path.realpath(SESSION_STORAGE_PATH)):
31
- raise ValueError(f"Path '{path}' is outside the storage boundary")
34
+ resolved = os.path.realpath(path)
35
+ if not any(resolved == os.path.realpath(m) or resolved.startswith(os.path.realpath(m) + os.sep) for m in _MOUNT_PATHS):
36
+ raise ValueError(f"Path '{path}' is not within any configured mount ({', '.join(_MOUNT_PATHS)})")
32
37
  return resolved
33
38
 
34
39
  @tool
35
40
  def file_read(path: str) -> str:
36
- """Read a file from persistent storage. The path is relative to the storage root."""
41
+ """Read a file from a mounted filesystem. Use the absolute path (e.g. /mnt/tools/data.txt)."""
37
42
  try:
38
43
  full_path = _safe_resolve(path)
39
44
  with open(full_path) as f:
@@ -45,7 +50,7 @@ def file_read(path: str) -> str:
45
50
 
46
51
  @tool
47
52
  def file_write(path: str, content: str) -> str:
48
- """Write content to a file in persistent storage. The path is relative to the storage root."""
53
+ """Write a file to a mounted filesystem. Use the absolute path (e.g. /mnt/tools/data.txt)."""
49
54
  try:
50
55
  full_path = _safe_resolve(path)
51
56
  parent = os.path.dirname(full_path)
@@ -60,25 +65,28 @@ def file_write(path: str, content: str) -> str:
60
65
  return f"Error writing '{path}': {e.strerror}"
61
66
 
62
67
  @tool
63
- def list_files(directory: str = "") -> str:
64
- """List files in persistent storage. The directory is relative to the storage root."""
68
+ def list_files(path: str) -> str:
69
+ """List files in a mounted filesystem directory. Use the absolute path (e.g. /mnt/tools)."""
65
70
  try:
66
- target = _safe_resolve(directory)
67
- entries = os.listdir(target)
71
+ full_path = _safe_resolve(path)
72
+ entries = os.listdir(full_path)
68
73
  return "\n".join(entries) if entries else "(empty directory)"
69
74
  except ValueError as e:
70
75
  return str(e)
71
76
  except OSError as e:
72
- return f"Error listing '{directory}': {e.strerror}"
77
+ return f"Error listing '{path}': {e.strerror}"
73
78
 
74
79
  tools.extend([file_read, file_write, list_files])
75
80
  {{/if}}
76
81
 
77
82
  SYSTEM_PROMPT = """
78
83
  You are a helpful assistant. Use tools when appropriate.
79
- {{#if sessionStorageMountPath}}
80
- You have persistent storage at {{sessionStorageMountPath}}. Use file tools to read and write files. Data persists across sessions.
81
- {{/if}}
84
+ {{#if needsOs}}
85
+ You have access to the following mounted filesystems. Use file_read, file_write, and list_files with full absolute paths:
86
+ {{#if sessionStorageMountPath}}- {{sessionStorageMountPath}}: ephemeral session storage (lost when session ends)
87
+ {{/if}}{{#each efsMounts}}- {{mountPath}}: EFS persistent storage (persists across sessions and agent restarts)
88
+ {{/each}}{{#each s3Mounts}}- {{mountPath}}: S3 Files persistent storage (durable, backed by S3)
89
+ {{/each}}{{/if}}
82
90
  """
83
91
 
84
92
  model = load_model()
@@ -9,14 +9,15 @@ description = "AgentCore A2A Agent using LangChain + LangGraph"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
11
11
  dependencies = [
12
- "a2a-sdk >= 0.2.0",
12
+ "a2a-sdk >= 0.2.0, < 1.0.0",
13
13
  {{#if (eq modelProvider "Anthropic")}}"langchain-anthropic >= 0.3.0",
14
14
  {{/if}}{{#if (eq modelProvider "Bedrock")}}"langchain-aws >= 0.2.0",
15
15
  {{/if}}{{#if (eq modelProvider "Gemini")}}"langchain-google-genai >= 2.0.0",
16
+ "google-genai >= 1.0.0, < 2.0.0",
16
17
  {{/if}}{{#if (eq modelProvider "OpenAI")}}"langchain-openai >= 0.2.0",
17
18
  {{/if}}"aws-opentelemetry-distro",
18
19
  "opentelemetry-instrumentation-langchain >= 0.59.0",
19
- "bedrock-agentcore[a2a] >= 1.0.3",
20
+ "bedrock-agentcore[a2a] >= 1.8.0",
20
21
  "botocore[crt] >= 1.35.0",
21
22
  "langgraph >= 0.2.0",
22
23
  ]