@aws/agentcore 0.3.0-preview.1.0

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 (213) hide show
  1. package/LICENSE +175 -0
  2. package/README.md +147 -0
  3. package/dist/assets/README.md +79 -0
  4. package/dist/assets/__tests__/__snapshots__/assets.snapshot.test.ts.snap +2862 -0
  5. package/dist/assets/__tests__/assets.snapshot.test.ts +139 -0
  6. package/dist/assets/agents/AGENTS.md +102 -0
  7. package/dist/assets/cdk/.prettierrc +8 -0
  8. package/dist/assets/cdk/README.md +14 -0
  9. package/dist/assets/cdk/bin/cdk.ts +50 -0
  10. package/dist/assets/cdk/cdk.json +88 -0
  11. package/dist/assets/cdk/gitignore.template +9 -0
  12. package/dist/assets/cdk/jest.config.js +9 -0
  13. package/dist/assets/cdk/lib/cdk-stack.ts +38 -0
  14. package/dist/assets/cdk/npmignore.template +6 -0
  15. package/dist/assets/cdk/package.json +30 -0
  16. package/dist/assets/cdk/test/cdk.test.ts +16 -0
  17. package/dist/assets/cdk/tsconfig.json +28 -0
  18. package/dist/assets/mcp/python/README.md +27 -0
  19. package/dist/assets/mcp/python/pyproject.toml +22 -0
  20. package/dist/assets/mcp/python/server.py +117 -0
  21. package/dist/assets/mcp/python-lambda/README.md +22 -0
  22. package/dist/assets/mcp/python-lambda/handler.py +144 -0
  23. package/dist/assets/mcp/python-lambda/pyproject.toml +15 -0
  24. package/dist/assets/python/autogen/base/README.md +41 -0
  25. package/dist/assets/python/autogen/base/gitignore.template +40 -0
  26. package/dist/assets/python/autogen/base/main.py +52 -0
  27. package/dist/assets/python/autogen/base/mcp_client/client.py +18 -0
  28. package/dist/assets/python/autogen/base/model/load.py +136 -0
  29. package/dist/assets/python/autogen/base/pyproject.toml +35 -0
  30. package/dist/assets/python/crewai/base/README.md +41 -0
  31. package/dist/assets/python/crewai/base/gitignore.template +40 -0
  32. package/dist/assets/python/crewai/base/main.py +55 -0
  33. package/dist/assets/python/crewai/base/model/load.py +133 -0
  34. package/dist/assets/python/crewai/base/pyproject.toml +32 -0
  35. package/dist/assets/python/googleadk/base/README.md +39 -0
  36. package/dist/assets/python/googleadk/base/gitignore.template +40 -0
  37. package/dist/assets/python/googleadk/base/main.py +84 -0
  38. package/dist/assets/python/googleadk/base/mcp_client/client.py +15 -0
  39. package/dist/assets/python/googleadk/base/model/load.py +41 -0
  40. package/dist/assets/python/googleadk/base/pyproject.toml +21 -0
  41. package/dist/assets/python/langchain_langgraph/base/README.md +41 -0
  42. package/dist/assets/python/langchain_langgraph/base/gitignore.template +40 -0
  43. package/dist/assets/python/langchain_langgraph/base/main.py +51 -0
  44. package/dist/assets/python/langchain_langgraph/base/mcp_client/client.py +19 -0
  45. package/dist/assets/python/langchain_langgraph/base/model/load.py +123 -0
  46. package/dist/assets/python/langchain_langgraph/base/pyproject.toml +37 -0
  47. package/dist/assets/python/openaiagents/base/README.md +39 -0
  48. package/dist/assets/python/openaiagents/base/gitignore.template +40 -0
  49. package/dist/assets/python/openaiagents/base/main.py +56 -0
  50. package/dist/assets/python/openaiagents/base/mcp_client/client.py +14 -0
  51. package/dist/assets/python/openaiagents/base/model/load.py +37 -0
  52. package/dist/assets/python/openaiagents/base/pyproject.toml +20 -0
  53. package/dist/assets/python/strands/base/README.md +41 -0
  54. package/dist/assets/python/strands/base/gitignore.template +41 -0
  55. package/dist/assets/python/strands/base/main.py +76 -0
  56. package/dist/assets/python/strands/base/mcp_client/client.py +12 -0
  57. package/dist/assets/python/strands/base/model/load.py +123 -0
  58. package/dist/assets/python/strands/base/pyproject.toml +23 -0
  59. package/dist/assets/python/strands/capabilities/memory/session.py +39 -0
  60. package/dist/assets/typescript/.gitkeep +0 -0
  61. package/dist/cli/index.mjs +985 -0
  62. package/dist/index.d.ts +9 -0
  63. package/dist/index.d.ts.map +1 -0
  64. package/dist/index.js +27 -0
  65. package/dist/index.js.map +1 -0
  66. package/dist/lib/constants.d.ts +25 -0
  67. package/dist/lib/constants.d.ts.map +1 -0
  68. package/dist/lib/constants.js +49 -0
  69. package/dist/lib/constants.js.map +1 -0
  70. package/dist/lib/errors/config.d.ts +49 -0
  71. package/dist/lib/errors/config.d.ts.map +1 -0
  72. package/dist/lib/errors/config.js +167 -0
  73. package/dist/lib/errors/config.js.map +1 -0
  74. package/dist/lib/errors/index.d.ts +2 -0
  75. package/dist/lib/errors/index.d.ts.map +1 -0
  76. package/dist/lib/errors/index.js +18 -0
  77. package/dist/lib/errors/index.js.map +1 -0
  78. package/dist/lib/index.d.ts +7 -0
  79. package/dist/lib/index.d.ts.map +1 -0
  80. package/dist/lib/index.js +39 -0
  81. package/dist/lib/index.js.map +1 -0
  82. package/dist/lib/packaging/errors.d.ts +16 -0
  83. package/dist/lib/packaging/errors.d.ts.map +1 -0
  84. package/dist/lib/packaging/errors.js +36 -0
  85. package/dist/lib/packaging/errors.js.map +1 -0
  86. package/dist/lib/packaging/helpers.d.ts +54 -0
  87. package/dist/lib/packaging/helpers.d.ts.map +1 -0
  88. package/dist/lib/packaging/helpers.js +461 -0
  89. package/dist/lib/packaging/helpers.js.map +1 -0
  90. package/dist/lib/packaging/index.d.ts +36 -0
  91. package/dist/lib/packaging/index.d.ts.map +1 -0
  92. package/dist/lib/packaging/index.js +89 -0
  93. package/dist/lib/packaging/index.js.map +1 -0
  94. package/dist/lib/packaging/node.d.ts +17 -0
  95. package/dist/lib/packaging/node.d.ts.map +1 -0
  96. package/dist/lib/packaging/node.js +108 -0
  97. package/dist/lib/packaging/node.js.map +1 -0
  98. package/dist/lib/packaging/python.d.ts +17 -0
  99. package/dist/lib/packaging/python.d.ts.map +1 -0
  100. package/dist/lib/packaging/python.js +162 -0
  101. package/dist/lib/packaging/python.js.map +1 -0
  102. package/dist/lib/packaging/types/index.d.ts +2 -0
  103. package/dist/lib/packaging/types/index.d.ts.map +1 -0
  104. package/dist/lib/packaging/types/index.js +3 -0
  105. package/dist/lib/packaging/types/index.js.map +1 -0
  106. package/dist/lib/packaging/types/packaging.d.ts +57 -0
  107. package/dist/lib/packaging/types/packaging.d.ts.map +1 -0
  108. package/dist/lib/packaging/types/packaging.js +3 -0
  109. package/dist/lib/packaging/types/packaging.js.map +1 -0
  110. package/dist/lib/packaging/uv.d.ts +7 -0
  111. package/dist/lib/packaging/uv.d.ts.map +1 -0
  112. package/dist/lib/packaging/uv.js +40 -0
  113. package/dist/lib/packaging/uv.js.map +1 -0
  114. package/dist/lib/schemas/io/config-io.d.ts +106 -0
  115. package/dist/lib/schemas/io/config-io.d.ts.map +1 -0
  116. package/dist/lib/schemas/io/config-io.js +293 -0
  117. package/dist/lib/schemas/io/config-io.js.map +1 -0
  118. package/dist/lib/schemas/io/index.d.ts +3 -0
  119. package/dist/lib/schemas/io/index.d.ts.map +1 -0
  120. package/dist/lib/schemas/io/index.js +17 -0
  121. package/dist/lib/schemas/io/index.js.map +1 -0
  122. package/dist/lib/schemas/io/path-resolver.d.ts +112 -0
  123. package/dist/lib/schemas/io/path-resolver.d.ts.map +1 -0
  124. package/dist/lib/schemas/io/path-resolver.js +195 -0
  125. package/dist/lib/schemas/io/path-resolver.js.map +1 -0
  126. package/dist/lib/utils/aws-account.d.ts +7 -0
  127. package/dist/lib/utils/aws-account.d.ts.map +1 -0
  128. package/dist/lib/utils/aws-account.js +24 -0
  129. package/dist/lib/utils/aws-account.js.map +1 -0
  130. package/dist/lib/utils/credentials.d.ts +86 -0
  131. package/dist/lib/utils/credentials.d.ts.map +1 -0
  132. package/dist/lib/utils/credentials.js +153 -0
  133. package/dist/lib/utils/credentials.js.map +1 -0
  134. package/dist/lib/utils/env.d.ts +22 -0
  135. package/dist/lib/utils/env.d.ts.map +1 -0
  136. package/dist/lib/utils/env.js +65 -0
  137. package/dist/lib/utils/env.js.map +1 -0
  138. package/dist/lib/utils/index.d.ts +7 -0
  139. package/dist/lib/utils/index.d.ts.map +1 -0
  140. package/dist/lib/utils/index.js +23 -0
  141. package/dist/lib/utils/index.js.map +1 -0
  142. package/dist/lib/utils/platform.d.ts +63 -0
  143. package/dist/lib/utils/platform.d.ts.map +1 -0
  144. package/dist/lib/utils/platform.js +88 -0
  145. package/dist/lib/utils/platform.js.map +1 -0
  146. package/dist/lib/utils/subprocess.d.ts +29 -0
  147. package/dist/lib/utils/subprocess.d.ts.map +1 -0
  148. package/dist/lib/utils/subprocess.js +94 -0
  149. package/dist/lib/utils/subprocess.js.map +1 -0
  150. package/dist/lib/utils/zod.d.ts +14 -0
  151. package/dist/lib/utils/zod.d.ts.map +1 -0
  152. package/dist/lib/utils/zod.js +32 -0
  153. package/dist/lib/utils/zod.js.map +1 -0
  154. package/dist/schema/constants.d.ts +82 -0
  155. package/dist/schema/constants.d.ts.map +1 -0
  156. package/dist/schema/constants.js +117 -0
  157. package/dist/schema/constants.js.map +1 -0
  158. package/dist/schema/index.d.ts +4 -0
  159. package/dist/schema/index.d.ts.map +1 -0
  160. package/dist/schema/index.js +21 -0
  161. package/dist/schema/index.js.map +1 -0
  162. package/dist/schema/schemas/agent-env.d.ts +75 -0
  163. package/dist/schema/schemas/agent-env.d.ts.map +1 -0
  164. package/dist/schema/schemas/agent-env.js +84 -0
  165. package/dist/schema/schemas/agent-env.js.map +1 -0
  166. package/dist/schema/schemas/agentcore-project.d.ts +88 -0
  167. package/dist/schema/schemas/agentcore-project.d.ts.map +1 -0
  168. package/dist/schema/schemas/agentcore-project.js +83 -0
  169. package/dist/schema/schemas/agentcore-project.js.map +1 -0
  170. package/dist/schema/schemas/aws-targets.d.ts +50 -0
  171. package/dist/schema/schemas/aws-targets.d.ts.map +1 -0
  172. package/dist/schema/schemas/aws-targets.js +49 -0
  173. package/dist/schema/schemas/aws-targets.js.map +1 -0
  174. package/dist/schema/schemas/deployed-state.d.ts +260 -0
  175. package/dist/schema/schemas/deployed-state.d.ts.map +1 -0
  176. package/dist/schema/schemas/deployed-state.js +100 -0
  177. package/dist/schema/schemas/deployed-state.js.map +1 -0
  178. package/dist/schema/schemas/index.d.ts +8 -0
  179. package/dist/schema/schemas/index.d.ts.map +1 -0
  180. package/dist/schema/schemas/index.js +25 -0
  181. package/dist/schema/schemas/index.js.map +1 -0
  182. package/dist/schema/schemas/mcp-defs.d.ts +52 -0
  183. package/dist/schema/schemas/mcp-defs.d.ts.map +1 -0
  184. package/dist/schema/schemas/mcp-defs.js +50 -0
  185. package/dist/schema/schemas/mcp-defs.js.map +1 -0
  186. package/dist/schema/schemas/mcp.d.ts +659 -0
  187. package/dist/schema/schemas/mcp.d.ts.map +1 -0
  188. package/dist/schema/schemas/mcp.js +283 -0
  189. package/dist/schema/schemas/mcp.js.map +1 -0
  190. package/dist/schema/schemas/primitives/index.d.ts +3 -0
  191. package/dist/schema/schemas/primitives/index.d.ts.map +1 -0
  192. package/dist/schema/schemas/primitives/index.js +9 -0
  193. package/dist/schema/schemas/primitives/index.js.map +1 -0
  194. package/dist/schema/schemas/primitives/memory.d.ts +42 -0
  195. package/dist/schema/schemas/primitives/memory.d.ts.map +1 -0
  196. package/dist/schema/schemas/primitives/memory.js +50 -0
  197. package/dist/schema/schemas/primitives/memory.js.map +1 -0
  198. package/dist/schema/schemas/zod-util.d.ts +10 -0
  199. package/dist/schema/schemas/zod-util.d.ts.map +1 -0
  200. package/dist/schema/schemas/zod-util.js +23 -0
  201. package/dist/schema/schemas/zod-util.js.map +1 -0
  202. package/dist/schema/types/index.d.ts +2 -0
  203. package/dist/schema/types/index.d.ts.map +1 -0
  204. package/dist/schema/types/index.js +18 -0
  205. package/dist/schema/types/index.js.map +1 -0
  206. package/dist/schema/types/path.d.ts +27 -0
  207. package/dist/schema/types/path.d.ts.map +1 -0
  208. package/dist/schema/types/path.js +13 -0
  209. package/dist/schema/types/path.js.map +1 -0
  210. package/package.json +111 -0
  211. package/scripts/bump-version.ts +442 -0
  212. package/scripts/check-old-cli.mjs +26 -0
  213. package/scripts/copy-assets.mjs +50 -0
@@ -0,0 +1,2862 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`Assets Directory Snapshots > CDK assets > cdk/cdk/.prettierrc should match snapshot 1`] = `
4
+ "{
5
+ "trailingComma": "es5",
6
+ "printWidth": 120,
7
+ "tabWidth": 2,
8
+ "semi": true,
9
+ "singleQuote": true,
10
+ "arrowParens": "avoid"
11
+ }
12
+ "
13
+ `;
14
+
15
+ exports[`Assets Directory Snapshots > CDK assets > cdk/cdk/README.md should match snapshot 1`] = `
16
+ "# Welcome to your CDK TypeScript project
17
+
18
+ This is a blank project for CDK development with TypeScript.
19
+
20
+ The \`cdk.json\` file tells the CDK Toolkit how to execute your app.
21
+
22
+ ## Useful commands
23
+
24
+ - \`npm run build\` compile typescript to js
25
+ - \`npm run watch\` watch for changes and compile
26
+ - \`npm run test\` perform the jest unit tests
27
+ - \`npx cdk deploy\` deploy this stack to your default AWS account/region
28
+ - \`npx cdk diff\` compare deployed stack with current state
29
+ - \`npx cdk synth\` emits the synthesized CloudFormation template
30
+ "
31
+ `;
32
+
33
+ exports[`Assets Directory Snapshots > CDK assets > cdk/cdk/bin/cdk.ts should match snapshot 1`] = `
34
+ "#!/usr/bin/env node
35
+ import { AgentCoreStack } from '../lib/cdk-stack';
36
+ import { ConfigIO, type AwsDeploymentTarget } from '@aws/agentcore-cdk';
37
+ import { App, type Environment } from 'aws-cdk-lib';
38
+ import * as path from 'path';
39
+
40
+ function toEnvironment(target: AwsDeploymentTarget): Environment {
41
+ return {
42
+ account: target.account,
43
+ region: target.region,
44
+ };
45
+ }
46
+
47
+ function toStackName(projectName: string, targetName: string): string {
48
+ return \`AgentCore-\${projectName}-\${targetName}\`;
49
+ }
50
+
51
+ async function main() {
52
+ // Config root is parent of cdk/ directory. The CLI sets process.cwd() to agentcore/cdk/.
53
+ const configRoot = path.resolve(process.cwd(), '..');
54
+ const configIO = new ConfigIO({ baseDir: configRoot });
55
+
56
+ const spec = await configIO.readProjectSpec();
57
+ const targets = await configIO.readAWSDeploymentTargets();
58
+
59
+ if (targets.length === 0) {
60
+ throw new Error('No deployment targets configured. Please define targets in agentcore/aws-targets.json');
61
+ }
62
+
63
+ const app = new App();
64
+
65
+ for (const target of targets) {
66
+ const env = toEnvironment(target);
67
+ const stackName = toStackName(spec.name, target.name);
68
+
69
+ new AgentCoreStack(app, stackName, {
70
+ spec,
71
+ env,
72
+ description: \`AgentCore stack for \${spec.name} deployed to \${target.name} (\${target.region})\`,
73
+ tags: {
74
+ 'agentcore:project-name': spec.name,
75
+ 'agentcore:target-name': target.name,
76
+ },
77
+ });
78
+ }
79
+
80
+ app.synth();
81
+ }
82
+
83
+ main();
84
+ "
85
+ `;
86
+
87
+ exports[`Assets Directory Snapshots > CDK assets > cdk/cdk/cdk.json should match snapshot 1`] = `
88
+ "{
89
+ "app": "node dist/bin/cdk.js",
90
+ "watch": {
91
+ "include": ["**"],
92
+ "exclude": ["README.md", "cdk*.json", "tsconfig.json", "package*.json", "yarn.lock", "node_modules", "dist", "test"]
93
+ },
94
+ "context": {
95
+ "@aws-cdk/aws-signer:signingProfileNamePassedToCfn": true,
96
+ "@aws-cdk/aws-ecs-patterns:secGroupsDisablesImplicitOpenListener": true,
97
+ "@aws-cdk/aws-lambda:recognizeLayerVersion": true,
98
+ "@aws-cdk/core:checkSecretUsage": true,
99
+ "@aws-cdk/core:target-partitions": ["aws", "aws-cn"],
100
+ "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
101
+ "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
102
+ "@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true,
103
+ "@aws-cdk/aws-iam:minimizePolicies": true,
104
+ "@aws-cdk/core:validateSnapshotRemovalPolicy": true,
105
+ "@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true,
106
+ "@aws-cdk/aws-s3:createDefaultLoggingPolicy": true,
107
+ "@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true,
108
+ "@aws-cdk/aws-apigateway:disableCloudWatchRole": true,
109
+ "@aws-cdk/core:enablePartitionLiterals": true,
110
+ "@aws-cdk/aws-events:eventsTargetQueueSameAccount": true,
111
+ "@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true,
112
+ "@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true,
113
+ "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true,
114
+ "@aws-cdk/aws-route53-patters:useCertificate": true,
115
+ "@aws-cdk/customresources:installLatestAwsSdkDefault": false,
116
+ "@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true,
117
+ "@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true,
118
+ "@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true,
119
+ "@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true,
120
+ "@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true,
121
+ "@aws-cdk/aws-redshift:columnId": true,
122
+ "@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true,
123
+ "@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true,
124
+ "@aws-cdk/aws-apigateway:requestValidatorUniqueId": true,
125
+ "@aws-cdk/aws-kms:aliasNameRef": true,
126
+ "@aws-cdk/aws-kms:applyImportedAliasPermissionsToPrincipal": true,
127
+ "@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true,
128
+ "@aws-cdk/core:includePrefixInUniqueNameGeneration": true,
129
+ "@aws-cdk/aws-efs:denyAnonymousAccess": true,
130
+ "@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true,
131
+ "@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": true,
132
+ "@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true,
133
+ "@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": true,
134
+ "@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": true,
135
+ "@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": true,
136
+ "@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": true,
137
+ "@aws-cdk/aws-cloudwatch-actions:changeLambdaPermissionLogicalIdForLambdaAction": true,
138
+ "@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse": true,
139
+ "@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2": true,
140
+ "@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope": true,
141
+ "@aws-cdk/aws-eks:nodegroupNameAttribute": true,
142
+ "@aws-cdk/aws-ec2:ebsDefaultGp3Volume": true,
143
+ "@aws-cdk/aws-ecs:removeDefaultDeploymentAlarm": true,
144
+ "@aws-cdk/custom-resources:logApiResponseDataPropertyTrueDefault": false,
145
+ "@aws-cdk/aws-s3:keepNotificationInImportedBucket": false,
146
+ "@aws-cdk/core:explicitStackTags": true,
147
+ "@aws-cdk/aws-ecs:enableImdsBlockingDeprecatedFeature": false,
148
+ "@aws-cdk/aws-ecs:disableEcsImdsBlocking": true,
149
+ "@aws-cdk/aws-ecs:reduceEc2FargateCloudWatchPermissions": true,
150
+ "@aws-cdk/aws-dynamodb:resourcePolicyPerReplica": true,
151
+ "@aws-cdk/aws-ec2:ec2SumTImeoutEnabled": true,
152
+ "@aws-cdk/aws-appsync:appSyncGraphQLAPIScopeLambdaPermission": true,
153
+ "@aws-cdk/aws-rds:setCorrectValueForDatabaseInstanceReadReplicaInstanceResourceId": true,
154
+ "@aws-cdk/core:cfnIncludeRejectComplexResourceUpdateCreatePolicyIntrinsics": true,
155
+ "@aws-cdk/aws-lambda-nodejs:sdkV3ExcludeSmithyPackages": true,
156
+ "@aws-cdk/aws-stepfunctions-tasks:fixRunEcsTaskPolicy": true,
157
+ "@aws-cdk/aws-ec2:bastionHostUseAmazonLinux2023ByDefault": true,
158
+ "@aws-cdk/aws-route53-targets:userPoolDomainNameMethodWithoutCustomResource": true,
159
+ "@aws-cdk/aws-elasticloadbalancingV2:albDualstackWithoutPublicIpv4SecurityGroupRulesDefault": true,
160
+ "@aws-cdk/aws-iam:oidcRejectUnauthorizedConnections": true,
161
+ "@aws-cdk/core:enableAdditionalMetadataCollection": true,
162
+ "@aws-cdk/aws-lambda:createNewPoliciesWithAddToRolePolicy": false,
163
+ "@aws-cdk/aws-s3:setUniqueReplicationRoleName": true,
164
+ "@aws-cdk/aws-events:requireEventBusPolicySid": true,
165
+ "@aws-cdk/core:aspectPrioritiesMutating": true,
166
+ "@aws-cdk/aws-dynamodb:retainTableReplica": true,
167
+ "@aws-cdk/aws-stepfunctions:useDistributedMapResultWriterV2": true,
168
+ "@aws-cdk/s3-notifications:addS3TrustKeyPolicyForSnsSubscriptions": true,
169
+ "@aws-cdk/aws-ec2:requirePrivateSubnetsForEgressOnlyInternetGateway": true,
170
+ "@aws-cdk/aws-s3:publicAccessBlockedByDefault": true,
171
+ "@aws-cdk/aws-lambda:useCdkManagedLogGroup": true,
172
+ "@aws-cdk/aws-elasticloadbalancingv2:networkLoadBalancerWithSecurityGroupByDefault": true,
173
+ "@aws-cdk/aws-ecs-patterns:uniqueTargetGroupId": true
174
+ }
175
+ }
176
+ "
177
+ `;
178
+
179
+ exports[`Assets Directory Snapshots > CDK assets > cdk/cdk/gitignore.template should match snapshot 1`] = `
180
+ "# Build output
181
+ dist/
182
+
183
+ # Dependencies
184
+ node_modules/
185
+
186
+ # CDK asset staging directory
187
+ .cdk.staging
188
+ cdk.out
189
+ "
190
+ `;
191
+
192
+ exports[`Assets Directory Snapshots > CDK assets > cdk/cdk/jest.config.js should match snapshot 1`] = `
193
+ "module.exports = {
194
+ testEnvironment: 'node',
195
+ roots: ['<rootDir>/test'],
196
+ testMatch: ['**/*.test.ts'],
197
+ transform: {
198
+ '^.+\\\\.tsx?$': 'ts-jest',
199
+ },
200
+ setupFilesAfterEnv: ['aws-cdk-lib/testhelpers/jest-autoclean'],
201
+ };
202
+ "
203
+ `;
204
+
205
+ exports[`Assets Directory Snapshots > CDK assets > cdk/cdk/lib/cdk-stack.ts should match snapshot 1`] = `
206
+ "import { AgentCoreApplication, type AgentCoreProjectSpec } from '@aws/agentcore-cdk';
207
+ import { CfnOutput, Stack, type StackProps } from 'aws-cdk-lib';
208
+ import { Construct } from 'constructs';
209
+
210
+ export interface AgentCoreStackProps extends StackProps {
211
+ /**
212
+ * The AgentCore project specification containing agents, memories, and credentials.
213
+ */
214
+ spec: AgentCoreProjectSpec;
215
+ }
216
+
217
+ /**
218
+ * CDK Stack that deploys AgentCore infrastructure.
219
+ *
220
+ * This is a thin wrapper that instantiates L3 constructs.
221
+ * All resource logic and outputs are contained within the L3 constructs.
222
+ */
223
+ export class AgentCoreStack extends Stack {
224
+ /** The AgentCore application containing all agent environments */
225
+ public readonly application: AgentCoreApplication;
226
+
227
+ constructor(scope: Construct, id: string, props: AgentCoreStackProps) {
228
+ super(scope, id, props);
229
+
230
+ const { spec } = props;
231
+
232
+ // Create AgentCoreApplication with all agents
233
+ this.application = new AgentCoreApplication(this, 'Application', {
234
+ spec,
235
+ });
236
+
237
+ // Stack-level output
238
+ new CfnOutput(this, 'StackNameOutput', {
239
+ description: 'Name of the CloudFormation Stack',
240
+ value: this.stackName,
241
+ });
242
+ }
243
+ }
244
+ "
245
+ `;
246
+
247
+ exports[`Assets Directory Snapshots > CDK assets > cdk/cdk/npmignore.template should match snapshot 1`] = `
248
+ "*.ts
249
+ !*.d.ts
250
+
251
+ # CDK asset staging directory
252
+ .cdk.staging
253
+ cdk.out
254
+ "
255
+ `;
256
+
257
+ exports[`Assets Directory Snapshots > CDK assets > cdk/cdk/package.json should match snapshot 1`] = `
258
+ "{
259
+ "name": "agentcore-cdk-app",
260
+ "version": "0.1.0",
261
+ "bin": {
262
+ "cdk": "dist/bin/cdk.js"
263
+ },
264
+ "scripts": {
265
+ "build": "tsc",
266
+ "watch": "tsc -w",
267
+ "test": "jest",
268
+ "cdk": "npm run build && cdk",
269
+ "clean": "rm -rf dist",
270
+ "format": "prettier --write .",
271
+ "format:check": "prettier --check ."
272
+ },
273
+ "devDependencies": {
274
+ "@types/jest": "^29.5.14",
275
+ "@types/node": "^24.10.1",
276
+ "jest": "^29.7.0",
277
+ "ts-jest": "^29.2.5",
278
+ "aws-cdk": "2.1100.1",
279
+ "prettier": "^3.4.2",
280
+ "typescript": "~5.9.3"
281
+ },
282
+ "dependencies": {
283
+ "@aws/agentcore-cdk": "^0.1.0-alpha.1",
284
+ "aws-cdk-lib": "2.234.1",
285
+ "constructs": "^10.0.0"
286
+ }
287
+ }
288
+ "
289
+ `;
290
+
291
+ exports[`Assets Directory Snapshots > CDK assets > cdk/cdk/test/cdk.test.ts should match snapshot 1`] = `
292
+ "// import * as cdk from 'aws-cdk-lib/core';
293
+ // import { Template } from 'aws-cdk-lib/assertions';
294
+ // import * as Cdk from '../lib/cdk-stack';
295
+
296
+ // example test. To run these tests, uncomment this file along with the
297
+ // example resource in lib/cdk-stack.ts
298
+ test('SQS Queue Created', () => {
299
+ // const app = new cdk.App();
300
+ // // WHEN
301
+ // const stack = new Cdk.CdkStack(app, 'MyTestStack');
302
+ // // THEN
303
+ // const template = Template.fromStack(stack);
304
+ // template.hasResourceProperties('AWS::SQS::Queue', {
305
+ // VisibilityTimeout: 300
306
+ // });
307
+ });
308
+ "
309
+ `;
310
+
311
+ exports[`Assets Directory Snapshots > CDK assets > cdk/cdk/tsconfig.json should match snapshot 1`] = `
312
+ "{
313
+ "compilerOptions": {
314
+ "target": "ES2022",
315
+ "module": "CommonJS",
316
+ "moduleResolution": "Node",
317
+ "lib": ["es2022"],
318
+ "declaration": true,
319
+ "strict": true,
320
+ "noImplicitAny": true,
321
+ "strictNullChecks": true,
322
+ "noImplicitThis": true,
323
+ "alwaysStrict": true,
324
+ "noUnusedLocals": false,
325
+ "noUnusedParameters": false,
326
+ "noImplicitReturns": true,
327
+ "noFallthroughCasesInSwitch": false,
328
+ "inlineSourceMap": true,
329
+ "inlineSources": true,
330
+ "experimentalDecorators": true,
331
+ "strictPropertyInitialization": false,
332
+ "skipLibCheck": true,
333
+ "typeRoots": ["./node_modules/@types"],
334
+ "rootDir": ".",
335
+ "outDir": "dist"
336
+ },
337
+ "include": ["bin/**/*", "lib/**/*", "test/**/*"],
338
+ "exclude": ["node_modules", "cdk.out", "dist"]
339
+ }
340
+ "
341
+ `;
342
+
343
+ exports[`Assets Directory Snapshots > File listing > should match the expected file structure > asset-file-listing 1`] = `
344
+ [
345
+ "AGENTS.md",
346
+ "README.md",
347
+ "agents/AGENTS.md",
348
+ "cdk/.prettierrc",
349
+ "cdk/README.md",
350
+ "cdk/bin/cdk.ts",
351
+ "cdk/cdk.json",
352
+ "cdk/gitignore.template",
353
+ "cdk/jest.config.js",
354
+ "cdk/lib/cdk-stack.ts",
355
+ "cdk/npmignore.template",
356
+ "cdk/package.json",
357
+ "cdk/test/cdk.test.ts",
358
+ "cdk/tsconfig.json",
359
+ "mcp/python-lambda/README.md",
360
+ "mcp/python-lambda/handler.py",
361
+ "mcp/python-lambda/pyproject.toml",
362
+ "mcp/python/README.md",
363
+ "mcp/python/pyproject.toml",
364
+ "mcp/python/server.py",
365
+ "python/autogen/base/README.md",
366
+ "python/autogen/base/gitignore.template",
367
+ "python/autogen/base/main.py",
368
+ "python/autogen/base/mcp_client/client.py",
369
+ "python/autogen/base/model/load.py",
370
+ "python/autogen/base/pyproject.toml",
371
+ "python/crewai/base/README.md",
372
+ "python/crewai/base/gitignore.template",
373
+ "python/crewai/base/main.py",
374
+ "python/crewai/base/model/load.py",
375
+ "python/crewai/base/pyproject.toml",
376
+ "python/googleadk/base/README.md",
377
+ "python/googleadk/base/gitignore.template",
378
+ "python/googleadk/base/main.py",
379
+ "python/googleadk/base/mcp_client/client.py",
380
+ "python/googleadk/base/model/load.py",
381
+ "python/googleadk/base/pyproject.toml",
382
+ "python/langchain_langgraph/base/README.md",
383
+ "python/langchain_langgraph/base/gitignore.template",
384
+ "python/langchain_langgraph/base/main.py",
385
+ "python/langchain_langgraph/base/mcp_client/client.py",
386
+ "python/langchain_langgraph/base/model/load.py",
387
+ "python/langchain_langgraph/base/pyproject.toml",
388
+ "python/openaiagents/base/README.md",
389
+ "python/openaiagents/base/gitignore.template",
390
+ "python/openaiagents/base/main.py",
391
+ "python/openaiagents/base/mcp_client/client.py",
392
+ "python/openaiagents/base/model/load.py",
393
+ "python/openaiagents/base/pyproject.toml",
394
+ "python/strands/base/README.md",
395
+ "python/strands/base/gitignore.template",
396
+ "python/strands/base/main.py",
397
+ "python/strands/base/mcp_client/client.py",
398
+ "python/strands/base/model/load.py",
399
+ "python/strands/base/pyproject.toml",
400
+ "python/strands/capabilities/memory/session.py",
401
+ "typescript/.gitkeep",
402
+ ]
403
+ `;
404
+
405
+ exports[`Assets Directory Snapshots > MCP assets > mcp/mcp/python/README.md should match snapshot 1`] = `
406
+ "# {{ name }}
407
+
408
+ This is a template MCP server generated by the AgentCore CLI.
409
+
410
+ Demonstrates HTTP tool patterns with proper error handling and retry logic.
411
+
412
+ ## Quick Start
413
+
414
+ \`\`\`bash
415
+ # Create and activate virtual environment
416
+ uv venv
417
+ source .venv/bin/activate # or .venv\\Scripts\\activate on Windows
418
+
419
+ # Install dependencies
420
+ uv sync
421
+
422
+ # Run the server
423
+ uv run server.py
424
+ \`\`\`
425
+
426
+ ## Available Tools
427
+
428
+ | Tool | Description |
429
+ | ----------------- | ------------------------------------------------------ |
430
+ | \`lookup_ip\` | Look up geolocation and network info for an IP address |
431
+ | \`get_random_user\` | Generate a random user profile for testing |
432
+ | \`fetch_post\` | Fetch a post by ID from JSONPlaceholder API |
433
+ "
434
+ `;
435
+
436
+ exports[`Assets Directory Snapshots > MCP assets > mcp/mcp/python/pyproject.toml should match snapshot 1`] = `
437
+ "[build-system]
438
+ requires = ["hatchling"]
439
+ build-backend = "hatchling.build"
440
+
441
+ [project]
442
+ name = "{{ name }}"
443
+ version = "0.1.0"
444
+ description = "MCP Server demonstrating HTTP tool patterns"
445
+ readme = "README.md"
446
+ requires-python = ">=3.10"
447
+ dependencies = [
448
+ "mcp[cli] >= 1.2.0",
449
+ "httpx >= 0.27.0",
450
+ "opentelemetry-distro",
451
+ "opentelemetry-exporter-otlp",
452
+ ]
453
+
454
+ [project.scripts]
455
+ server = "server:main"
456
+
457
+ [tool.hatch.build.targets.wheel]
458
+ packages = ["."]
459
+ "
460
+ `;
461
+
462
+ exports[`Assets Directory Snapshots > MCP assets > mcp/mcp/python/server.py should match snapshot 1`] = `
463
+ """"
464
+ MCP Server demonstrating HTTP tool patterns.
465
+
466
+ This template shows:
467
+ - Async HTTP boundaries with proper error handling
468
+ - Retry logic and partial failure
469
+ - Response parsing and validation
470
+
471
+ Run with: uv run server.py
472
+ """
473
+
474
+ import logging
475
+ from typing import Any
476
+
477
+ import httpx
478
+ from mcp.server.fastmcp import FastMCP
479
+
480
+ logging.basicConfig(level=logging.INFO, format="%(levelname)s - %(message)s")
481
+ logger = logging.getLogger(__name__)
482
+
483
+ mcp = FastMCP("tools")
484
+
485
+ HTTP_TIMEOUT = 10.0
486
+ MAX_RETRIES = 2
487
+
488
+
489
+ async def fetch_json(url: str, headers: dict[str, str] | None = None) -> dict[str, Any] | None:
490
+ """Make an HTTP GET request with retry logic."""
491
+ async with httpx.AsyncClient() as client:
492
+ for attempt in range(MAX_RETRIES):
493
+ try:
494
+ response = await client.get(url, headers=headers, timeout=HTTP_TIMEOUT)
495
+ response.raise_for_status()
496
+ return response.json()
497
+ except httpx.TimeoutException:
498
+ logger.warning(f"Timeout on attempt {attempt + 1} for {url}")
499
+ except httpx.HTTPStatusError as e:
500
+ logger.error(f"HTTP {e.response.status_code} for {url}")
501
+ return None
502
+ except httpx.RequestError as e:
503
+ logger.error(f"Request failed: {e}")
504
+ return None
505
+ return None
506
+
507
+
508
+ @mcp.tool()
509
+ async def lookup_ip(ip_address: str) -> str:
510
+ """Look up geolocation and network info for an IP address.
511
+
512
+ Args:
513
+ ip_address: IPv4 or IPv6 address to look up
514
+ """
515
+ data = await fetch_json(f"http://ip-api.com/json/{ip_address}")
516
+
517
+ if not data:
518
+ return f"Failed to look up IP: {ip_address}"
519
+
520
+ if data.get("status") == "fail":
521
+ return f"Lookup failed: {data.get('message', 'unknown error')}"
522
+
523
+ return (
524
+ f"IP: {data['query']}\\n"
525
+ f"Location: {data['city']}, {data['regionName']}, {data['country']}\\n"
526
+ f"ISP: {data['isp']}\\n"
527
+ f"Organization: {data['org']}\\n"
528
+ f"Timezone: {data['timezone']}"
529
+ )
530
+
531
+
532
+ @mcp.tool()
533
+ async def get_random_user() -> str:
534
+ """Generate a random user profile for testing or mock data."""
535
+ data = await fetch_json("https://randomuser.me/api/")
536
+
537
+ if not data or "results" not in data:
538
+ return "Failed to generate random user."
539
+
540
+ user = data["results"][0]
541
+ name = user["name"]
542
+ location = user["location"]
543
+
544
+ return (
545
+ f"Name: {name['first']} {name['last']}\\n"
546
+ f"Email: {user['email']}\\n"
547
+ f"Location: {location['city']}, {location['country']}\\n"
548
+ f"Phone: {user['phone']}"
549
+ )
550
+
551
+
552
+ @mcp.tool()
553
+ async def fetch_post(post_id: int) -> str:
554
+ """Fetch a post by ID from JSONPlaceholder API.
555
+
556
+ Args:
557
+ post_id: The post ID (1-100)
558
+ """
559
+ if not 1 <= post_id <= 100:
560
+ return "Post ID must be between 1 and 100."
561
+
562
+ data = await fetch_json(f"https://jsonplaceholder.typicode.com/posts/{post_id}")
563
+
564
+ if not data:
565
+ return f"Failed to fetch post {post_id}."
566
+
567
+ return (
568
+ f"Post #{data['id']}\\n"
569
+ f"Title: {data['title']}\\n\\n"
570
+ f"{data['body']}"
571
+ )
572
+
573
+
574
+ def main():
575
+ mcp.run(transport="stdio")
576
+
577
+
578
+ if __name__ == "__main__":
579
+ main()
580
+ "
581
+ `;
582
+
583
+ exports[`Assets Directory Snapshots > MCP assets > mcp/mcp/python-lambda/README.md should match snapshot 1`] = `
584
+ "# {{ Name }}
585
+
586
+ Lambda-based tools for AgentCore Gateway.
587
+
588
+ ## Tools
589
+
590
+ - \`lookup_ip\` - Look up geolocation for an IP address
591
+ - \`get_random_user\` - Generate random user profile
592
+ - \`fetch_post\` - Fetch a post by ID
593
+
594
+ ## Gateway Integration
595
+
596
+ Tools are invoked via AgentCore Gateway. The tool name is passed in:
597
+ \`context.client_context.custom["bedrockAgentCoreToolName"]\`
598
+
599
+ Format: \`{target_name}___{tool_name}\`
600
+
601
+ ## Adding New Tools
602
+
603
+ 1. Define the tool function with the \`@tool("tool_name")\` decorator
604
+ 2. Add the tool definition to \`mcp-defs.json\` in your agentcore project
605
+ 3. The tool will be automatically routed by the handler
606
+ "
607
+ `;
608
+
609
+ exports[`Assets Directory Snapshots > MCP assets > mcp/mcp/python-lambda/handler.py should match snapshot 1`] = `
610
+ """"
611
+ Lambda handler for AgentCore Gateway tools.
612
+
613
+ This template mirrors the FastMCP server tools but runs as a Lambda function
614
+ behind an AgentCore Gateway.
615
+
616
+ Tool routing uses bedrockAgentCoreToolName from client context:
617
+ Format: {target_name}___{tool_name}
618
+ """
619
+ import json
620
+ import logging
621
+ import urllib.request
622
+ import urllib.error
623
+ from typing import Any, Dict, Optional
624
+
625
+ logger = logging.getLogger()
626
+ logger.setLevel(logging.INFO)
627
+
628
+ HTTP_TIMEOUT = 10
629
+ TOOLS = {}
630
+
631
+
632
+ def tool(name: str):
633
+ """Decorator to register a tool handler."""
634
+ def decorator(func):
635
+ TOOLS[name] = func
636
+ return func
637
+ return decorator
638
+
639
+
640
+ def lambda_handler(event: Dict[str, Any], context) -> Dict[str, Any]:
641
+ """Route incoming gateway requests to the appropriate tool."""
642
+ try:
643
+ extended_name = context.client_context.custom.get("bedrockAgentCoreToolName", "")
644
+ tool_name = None
645
+
646
+ if "___" in extended_name:
647
+ tool_name = extended_name.split("___", 1)[1]
648
+
649
+ if not tool_name:
650
+ return _response(400, {"error": "Missing tool name in bedrockAgentCoreToolName"})
651
+
652
+ handler = TOOLS.get(tool_name)
653
+ if not handler:
654
+ return _response(400, {"error": f"Unknown tool: {tool_name}"})
655
+
656
+ result = handler(event)
657
+ return _response(200, {"result": result})
658
+
659
+ except Exception as e:
660
+ logger.exception("Tool execution failed")
661
+ return _response(500, {"error": str(e)})
662
+
663
+
664
+ def _response(status_code: int, body: Dict[str, Any]) -> Dict[str, Any]:
665
+ """Consistent JSON response wrapper."""
666
+ return {"statusCode": status_code, "body": json.dumps(body)}
667
+
668
+
669
+ def _fetch_json(url: str) -> Optional[Dict[str, Any]]:
670
+ """Fetch JSON from URL with error handling."""
671
+ try:
672
+ req = urllib.request.Request(url, headers={"User-Agent": "AgentCore-Tool/1.0"})
673
+ with urllib.request.urlopen(req, timeout=HTTP_TIMEOUT) as resp:
674
+ return json.loads(resp.read().decode())
675
+ except (urllib.error.URLError, json.JSONDecodeError) as e:
676
+ logger.warning(f"Failed to fetch {url}: {e}")
677
+ return None
678
+
679
+
680
+ @tool("{{Name}}_lookup_ip")
681
+ def lookup_ip(event: Dict[str, Any]) -> str:
682
+ """Look up geolocation and network info for an IP address.
683
+
684
+ Args:
685
+ ip_address: IPv4 or IPv6 address to look up
686
+ """
687
+ ip_address = event.get("ip_address", "")
688
+ if not ip_address:
689
+ return "Missing required parameter: ip_address"
690
+
691
+ data = _fetch_json(f"http://ip-api.com/json/{ip_address}")
692
+ if not data:
693
+ return f"Failed to look up IP: {ip_address}"
694
+
695
+ if data.get("status") == "fail":
696
+ return f"Lookup failed: {data.get('message', 'unknown error')}"
697
+
698
+ return (
699
+ f"IP: {data['query']}\\n"
700
+ f"Location: {data['city']}, {data['regionName']}, {data['country']}\\n"
701
+ f"ISP: {data['isp']}\\n"
702
+ f"Organization: {data['org']}\\n"
703
+ f"Timezone: {data['timezone']}"
704
+ )
705
+
706
+
707
+ @tool("{{Name}}_get_random_user")
708
+ def get_random_user(event: Dict[str, Any]) -> str:
709
+ """Generate a random user profile for testing or mock data."""
710
+ data = _fetch_json("https://randomuser.me/api/")
711
+ if not data or "results" not in data:
712
+ return "Failed to generate random user."
713
+
714
+ user = data["results"][0]
715
+ name = user["name"]
716
+ location = user["location"]
717
+
718
+ return (
719
+ f"Name: {name['first']} {name['last']}\\n"
720
+ f"Email: {user['email']}\\n"
721
+ f"Location: {location['city']}, {location['country']}\\n"
722
+ f"Phone: {user['phone']}"
723
+ )
724
+
725
+
726
+ @tool("{{Name}}_fetch_post")
727
+ def fetch_post(event: Dict[str, Any]) -> str:
728
+ """Fetch a post by ID from JSONPlaceholder API.
729
+
730
+ Args:
731
+ post_id: The post ID (1-100)
732
+ """
733
+ post_id = event.get("post_id")
734
+ if post_id is None:
735
+ return "Missing required parameter: post_id"
736
+
737
+ try:
738
+ post_id = int(post_id)
739
+ except (TypeError, ValueError):
740
+ return "post_id must be an integer"
741
+
742
+ if not 1 <= post_id <= 100:
743
+ return "Post ID must be between 1 and 100."
744
+
745
+ data = _fetch_json(f"https://jsonplaceholder.typicode.com/posts/{post_id}")
746
+ if not data:
747
+ return f"Failed to fetch post {post_id}."
748
+
749
+ return (
750
+ f"Post #{data['id']}\\n"
751
+ f"Title: {data['title']}\\n\\n"
752
+ f"{data['body']}"
753
+ )
754
+ "
755
+ `;
756
+
757
+ exports[`Assets Directory Snapshots > MCP assets > mcp/mcp/python-lambda/pyproject.toml should match snapshot 1`] = `
758
+ "[build-system]
759
+ requires = ["hatchling"]
760
+ build-backend = "hatchling.build"
761
+
762
+ [project]
763
+ name = "{{ name }}"
764
+ version = "0.1.0"
765
+ description = "Lambda tools for AgentCore Gateway"
766
+ readme = "README.md"
767
+ requires-python = ">=3.10"
768
+ # No external dependencies - uses stdlib only
769
+ dependencies = []
770
+
771
+ [tool.hatch.build.targets.wheel]
772
+ packages = ["."]
773
+ "
774
+ `;
775
+
776
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/autogen/base/README.md should match snapshot 1`] = `
777
+ "This is a project generated by the agentcore create CLI tool!
778
+
779
+ # Layout
780
+
781
+ There is one directory with generated application code, \`src/\` . At the root, there is a \`.gitignore\` file, a
782
+ \`.agentcore\` folder which represents the configurations and state associated with this project. Other \`agentcore\`
783
+ commands like \`deploy\`, \`dev\`, and \`invoke\` rely on the configuration stored here.
784
+
785
+ ## src/
786
+
787
+ The main entrypoint to your app is defined in \`src/main.py\`. Using the AgentCore SDK \`@app.entrypoint\` decorator, this
788
+ file defines a Starlette ASGI app with the AutoGen framework running within.
789
+
790
+ \`src/model/load.py\` instantiates your chosen model provider.
791
+
792
+ ## Environment Variables
793
+
794
+ | Variable | Required | Description |
795
+ | ------------------------------ | --------------- | ---------------------------------------------------------------- |
796
+ | \`AGENTCORE_IDENTITY_OPENAI\` | Yes (OpenAI) | OpenAI API key (local) or Identity provider name (deployed) |
797
+ | \`AGENTCORE_IDENTITY_ANTHROPIC\` | Yes (Anthropic) | Anthropic API key (local) or Identity provider name (deployed) |
798
+ | \`AGENTCORE_IDENTITY_GEMINI\` | Yes (Gemini) | Gemini API key (local) or Identity provider name (deployed) |
799
+ | \`LOCAL_DEV\` | No | Set to \`1\` to use \`agentcore/.env\` instead of AgentCore Identity |
800
+
801
+ # Developing locally
802
+
803
+ If installation was successful, a virtual environment is already created with dependencies installed.
804
+
805
+ Run \`source .venv/bin/activate\` before developing.
806
+
807
+ \`agentcore dev\` will start a local server on 0.0.0.0:8080.
808
+
809
+ In a new terminal, you can invoke that server with:
810
+
811
+ \`agentcore invoke --dev "What can you do"\`
812
+
813
+ # Deployment
814
+
815
+ After providing credentials, \`agentcore deploy\` will deploy your project into Amazon Bedrock AgentCore.
816
+
817
+ Use \`agentcore invoke\` to invoke your deployed agent.
818
+ "
819
+ `;
820
+
821
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/autogen/base/gitignore.template should match snapshot 1`] = `
822
+ "# Environment variables
823
+ .env
824
+
825
+ # Python
826
+ __pycache__/
827
+ *.py[cod]
828
+ *$py.class
829
+ *.so
830
+ .Python
831
+ build/
832
+ develop-eggs/
833
+ dist/
834
+ downloads/
835
+ eggs/
836
+ .eggs/
837
+ lib/
838
+ lib64/
839
+ parts/
840
+ sdist/
841
+ var/
842
+ wheels/
843
+ *.egg-info/
844
+ .installed.cfg
845
+ *.egg
846
+
847
+ # Virtual environments
848
+ venv/
849
+ ENV/
850
+ env/
851
+
852
+ # IDE
853
+ .vscode/
854
+ .idea/
855
+ *.swp
856
+ *.swo
857
+ *~
858
+
859
+ # OS
860
+ .DS_Store
861
+ Thumbs.db
862
+ "
863
+ `;
864
+
865
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/autogen/base/main.py should match snapshot 1`] = `
866
+ "import os
867
+ from autogen_agentchat.agents import AssistantAgent
868
+ from autogen_core.tools import FunctionTool
869
+ from bedrock_agentcore.runtime import BedrockAgentCoreApp
870
+ from model.load import load_model
871
+ from mcp_client.client import get_streamable_http_mcp_tools
872
+
873
+ app = BedrockAgentCoreApp()
874
+ log = app.logger
875
+
876
+
877
+ # Define a simple function tool
878
+ def add_numbers(a: int, b: int) -> int:
879
+ """Return the sum of two numbers"""
880
+ return a + b
881
+
882
+
883
+ add_numbers_tool = FunctionTool(
884
+ add_numbers, description="Return the sum of two numbers"
885
+ )
886
+
887
+ # Define a collection of tools used by the model
888
+ tools = [add_numbers_tool]
889
+
890
+
891
+ @app.entrypoint
892
+ async def invoke(payload, context):
893
+ log.info("Invoking Agent.....")
894
+
895
+ # Get MCP Tools
896
+ mcp_tools = await get_streamable_http_mcp_tools()
897
+
898
+ # Define an AssistantAgent with the model and tools
899
+ agent = AssistantAgent(
900
+ name="{{ name }}",
901
+ model_client=load_model(),
902
+ tools=tools + mcp_tools,
903
+ system_message="You are a helpful assistant. Use tools when appropriate.",
904
+ )
905
+
906
+ # Process the user prompt
907
+ prompt = payload.get("prompt", "What can you help me with?")
908
+
909
+ # Run the agent
910
+ result = await agent.run(task=prompt)
911
+
912
+ # Return result
913
+ return {"result": result.messages[-1].content}
914
+
915
+
916
+ if __name__ == "__main__":
917
+ app.run()
918
+ "
919
+ `;
920
+
921
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/autogen/base/mcp_client/client.py should match snapshot 1`] = `
922
+ "from typing import List
923
+ from autogen_ext.tools.mcp import (
924
+ StreamableHttpMcpToolAdapter,
925
+ StreamableHttpServerParams,
926
+ mcp_server_tools,
927
+ )
928
+
929
+ # ExaAI provides information about code through web searches, crawling and code context searches through their platform. Requires no authentication
930
+ EXAMPLE_MCP_ENDPOINT = "https://mcp.exa.ai/mcp"
931
+
932
+
933
+ async def get_streamable_http_mcp_tools() -> List[StreamableHttpMcpToolAdapter]:
934
+ """
935
+ Returns MCP Tools compatible with AutoGen.
936
+ """
937
+ # to use an MCP server that supports bearer authentication, add headers={"Authorization": f"Bearer {access_token}"}
938
+ server_params = StreamableHttpServerParams(url=EXAMPLE_MCP_ENDPOINT)
939
+ return await mcp_server_tools(server_params)
940
+ "
941
+ `;
942
+
943
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/autogen/base/model/load.py should match snapshot 1`] = `
944
+ "{{#if (eq modelProvider "Bedrock")}}
945
+ import os
946
+ from autogen_ext.models.anthropic import AnthropicBedrockChatCompletionClient
947
+ from autogen_core.models import ModelInfo, ModelFamily
948
+
949
+ # Uses global inference profile for Claude Sonnet 4.5
950
+ # https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-support.html
951
+ MODEL_ID = "global.anthropic.claude-sonnet-4-5-20250929-v1:0"
952
+
953
+
954
+ def load_model() -> AnthropicBedrockChatCompletionClient:
955
+ """Get Bedrock model client using IAM credentials."""
956
+ return AnthropicBedrockChatCompletionClient(
957
+ model=MODEL_ID,
958
+ model_info=ModelInfo(
959
+ vision=False,
960
+ function_calling=True,
961
+ json_output=False,
962
+ family=ModelFamily.CLAUDE_4_SONNET,
963
+ structured_output=True
964
+ ),
965
+ bedrock_info={"aws_region": os.environ.get("AWS_REGION", "us-east-1")}
966
+ )
967
+ {{/if}}
968
+ {{#if (eq modelProvider "Anthropic")}}
969
+ import os
970
+ from autogen_ext.models.anthropic import AnthropicChatCompletionClient
971
+ from bedrock_agentcore.identity.auth import requires_api_key
972
+
973
+ IDENTITY_PROVIDER_NAME = "{{identityProviders.[0].name}}"
974
+ IDENTITY_ENV_VAR = "{{identityProviders.[0].envVarName}}"
975
+
976
+
977
+ @requires_api_key(provider_name=IDENTITY_PROVIDER_NAME)
978
+ def _agentcore_identity_api_key_provider(api_key: str) -> str:
979
+ """Fetch API key from AgentCore Identity."""
980
+ return api_key
981
+
982
+
983
+ def _get_api_key() -> str:
984
+ """
985
+ Uses AgentCore Identity for API key management in deployed environments.
986
+ For local development, run via 'agentcore dev' which loads agentcore/.env.
987
+ """
988
+ if os.getenv("LOCAL_DEV") == "1":
989
+ api_key = os.getenv(IDENTITY_ENV_VAR)
990
+ if not api_key:
991
+ raise RuntimeError(
992
+ f"{IDENTITY_ENV_VAR} not found. Add {IDENTITY_ENV_VAR}=your-key to .env.local"
993
+ )
994
+ return api_key
995
+ return _agentcore_identity_api_key_provider()
996
+
997
+
998
+ def load_model() -> AnthropicChatCompletionClient:
999
+ """Get authenticated Anthropic model client."""
1000
+ return AnthropicChatCompletionClient(
1001
+ model="claude-sonnet-4-5-20250929",
1002
+ api_key=_get_api_key()
1003
+ )
1004
+ {{/if}}
1005
+ {{#if (eq modelProvider "OpenAI")}}
1006
+ import os
1007
+ from autogen_ext.models.openai import OpenAIChatCompletionClient
1008
+ from bedrock_agentcore.identity.auth import requires_api_key
1009
+
1010
+ IDENTITY_PROVIDER_NAME = "{{identityProviders.[0].name}}"
1011
+ IDENTITY_ENV_VAR = "{{identityProviders.[0].envVarName}}"
1012
+
1013
+
1014
+ @requires_api_key(provider_name=IDENTITY_PROVIDER_NAME)
1015
+ def _agentcore_identity_api_key_provider(api_key: str) -> str:
1016
+ """Fetch API key from AgentCore Identity."""
1017
+ return api_key
1018
+
1019
+
1020
+ def _get_api_key() -> str:
1021
+ """
1022
+ Uses AgentCore Identity for API key management in deployed environments.
1023
+ For local development, run via 'agentcore dev' which loads agentcore/.env.
1024
+ """
1025
+ if os.getenv("LOCAL_DEV") == "1":
1026
+ api_key = os.getenv(IDENTITY_ENV_VAR)
1027
+ if not api_key:
1028
+ raise RuntimeError(
1029
+ f"{IDENTITY_ENV_VAR} not found. Add {IDENTITY_ENV_VAR}=your-key to .env.local"
1030
+ )
1031
+ return api_key
1032
+ return _agentcore_identity_api_key_provider()
1033
+
1034
+
1035
+ def load_model() -> OpenAIChatCompletionClient:
1036
+ """Get authenticated OpenAI model client."""
1037
+ return OpenAIChatCompletionClient(
1038
+ model="gpt-4o",
1039
+ api_key=_get_api_key()
1040
+ )
1041
+ {{/if}}
1042
+ {{#if (eq modelProvider "Gemini")}}
1043
+ import os
1044
+ from autogen_ext.models.openai import OpenAIChatCompletionClient
1045
+ from bedrock_agentcore.identity.auth import requires_api_key
1046
+
1047
+ IDENTITY_PROVIDER_NAME = "{{identityProviders.[0].name}}"
1048
+ IDENTITY_ENV_VAR = "{{identityProviders.[0].envVarName}}"
1049
+
1050
+
1051
+ @requires_api_key(provider_name=IDENTITY_PROVIDER_NAME)
1052
+ def _agentcore_identity_api_key_provider(api_key: str) -> str:
1053
+ """Fetch API key from AgentCore Identity."""
1054
+ return api_key
1055
+
1056
+
1057
+ def _get_api_key() -> str:
1058
+ """
1059
+ Uses AgentCore Identity for API key management in deployed environments.
1060
+ For local development, run via 'agentcore dev' which loads agentcore/.env.
1061
+ """
1062
+ if os.getenv("LOCAL_DEV") == "1":
1063
+ api_key = os.getenv(IDENTITY_ENV_VAR)
1064
+ if not api_key:
1065
+ raise RuntimeError(
1066
+ f"{IDENTITY_ENV_VAR} not found. Add {IDENTITY_ENV_VAR}=your-key to .env.local"
1067
+ )
1068
+ return api_key
1069
+ return _agentcore_identity_api_key_provider()
1070
+
1071
+
1072
+ def load_model() -> OpenAIChatCompletionClient:
1073
+ """Get authenticated Gemini model client via OpenAI-compatible API."""
1074
+ return OpenAIChatCompletionClient(
1075
+ model="gemini-2.0-flash",
1076
+ api_key=_get_api_key(),
1077
+ base_url="https://generativelanguage.googleapis.com/v1beta/openai/"
1078
+ )
1079
+ {{/if}}
1080
+ "
1081
+ `;
1082
+
1083
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/autogen/base/pyproject.toml should match snapshot 1`] = `
1084
+ "[build-system]
1085
+ requires = ["hatchling"]
1086
+ build-backend = "hatchling.build"
1087
+
1088
+ [project]
1089
+ name = "{{ name }}"
1090
+ version = "0.1.0"
1091
+ description = "AgentCore Runtime Application using AutoGen SDK"
1092
+ readme = "README.md"
1093
+ requires-python = ">=3.10"
1094
+ dependencies = [
1095
+ "autogen-agentchat >= 0.7.5",
1096
+ "autogen-ext[mcp] >= 0.7.5",
1097
+ "opentelemetry-distro",
1098
+ "opentelemetry-exporter-otlp",
1099
+ "bedrock-agentcore >= 1.0.3",
1100
+ "botocore[crt] >= 1.35.0",
1101
+ "python-dotenv >= 1.0.1",
1102
+ "tiktoken",
1103
+ {{#if (eq modelProvider "Bedrock")}}
1104
+ "autogen-ext[anthropic] >= 0.7.5",
1105
+ {{/if}}
1106
+ {{#if (eq modelProvider "Anthropic")}}
1107
+ "autogen-ext[anthropic] >= 0.7.5",
1108
+ {{/if}}
1109
+ {{#if (eq modelProvider "OpenAI")}}
1110
+ "autogen-ext[openai] >= 0.7.5",
1111
+ {{/if}}
1112
+ {{#if (eq modelProvider "Gemini")}}
1113
+ "autogen-ext[openai] >= 0.7.5",
1114
+ {{/if}}
1115
+ ]
1116
+
1117
+ [tool.hatch.build.targets.wheel]
1118
+ packages = ["."]
1119
+ "
1120
+ `;
1121
+
1122
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/crewai/base/README.md should match snapshot 1`] = `
1123
+ "This is a project generated by the agentcore create CLI tool!
1124
+
1125
+ # Layout
1126
+
1127
+ There is one directory with generated application code, \`src/\` . At the root, there is a \`.gitignore\` file, a
1128
+ \`.agentcore\` folder which represents the configurations and state associated with this project. Other \`agentcore\`
1129
+ commands like \`deploy\`, \`dev\`, and \`invoke\` rely on the configuration stored here.
1130
+
1131
+ ## src/
1132
+
1133
+ The main entrypoint to your app is defined in \`src/main.py\`. Using the AgentCore SDK \`@app.entrypoint\` decorator, this
1134
+ file defines a Starlette ASGI app with the CrewAI framework running within.
1135
+
1136
+ \`src/model/load.py\` instantiates your chosen model provider.
1137
+
1138
+ ## Environment Variables
1139
+
1140
+ | Variable | Required | Description |
1141
+ | ------------------------------ | --------------- | ---------------------------------------------------------------- |
1142
+ | \`AGENTCORE_IDENTITY_OPENAI\` | Yes (OpenAI) | OpenAI API key (local) or Identity provider name (deployed) |
1143
+ | \`AGENTCORE_IDENTITY_ANTHROPIC\` | Yes (Anthropic) | Anthropic API key (local) or Identity provider name (deployed) |
1144
+ | \`AGENTCORE_IDENTITY_GEMINI\` | Yes (Gemini) | Gemini API key (local) or Identity provider name (deployed) |
1145
+ | \`LOCAL_DEV\` | No | Set to \`1\` to use \`agentcore/.env\` instead of AgentCore Identity |
1146
+
1147
+ # Developing locally
1148
+
1149
+ If installation was successful, a virtual environment is already created with dependencies installed.
1150
+
1151
+ Run \`source .venv/bin/activate\` before developing.
1152
+
1153
+ \`agentcore dev\` will start a local server on 0.0.0.0:8080.
1154
+
1155
+ In a new terminal, you can invoke that server with:
1156
+
1157
+ \`agentcore invoke --dev "What can you do"\`
1158
+
1159
+ # Deployment
1160
+
1161
+ After providing credentials, \`agentcore deploy\` will deploy your project into Amazon Bedrock AgentCore.
1162
+
1163
+ Use \`agentcore invoke\` to invoke your deployed agent.
1164
+ "
1165
+ `;
1166
+
1167
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/crewai/base/gitignore.template should match snapshot 1`] = `
1168
+ "# Environment variables
1169
+ .env
1170
+
1171
+ # Python
1172
+ __pycache__/
1173
+ *.py[cod]
1174
+ *$py.class
1175
+ *.so
1176
+ .Python
1177
+ build/
1178
+ develop-eggs/
1179
+ dist/
1180
+ downloads/
1181
+ eggs/
1182
+ .eggs/
1183
+ lib/
1184
+ lib64/
1185
+ parts/
1186
+ sdist/
1187
+ var/
1188
+ wheels/
1189
+ *.egg-info/
1190
+ .installed.cfg
1191
+ *.egg
1192
+
1193
+ # Virtual environments
1194
+ venv/
1195
+ ENV/
1196
+ env/
1197
+
1198
+ # IDE
1199
+ .vscode/
1200
+ .idea/
1201
+ *.swp
1202
+ *.swo
1203
+ *~
1204
+
1205
+ # OS
1206
+ .DS_Store
1207
+ Thumbs.db
1208
+ "
1209
+ `;
1210
+
1211
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/crewai/base/main.py should match snapshot 1`] = `
1212
+ "from crewai import Agent, Crew, Task, Process
1213
+ from crewai.tools import tool
1214
+ from bedrock_agentcore.runtime import BedrockAgentCoreApp
1215
+ from model.load import load_model
1216
+
1217
+ app = BedrockAgentCoreApp()
1218
+ log = app.logger
1219
+
1220
+
1221
+ # Define a simple function tool
1222
+ @tool
1223
+ def add_numbers(a: int, b: int) -> int:
1224
+ """Return the sum of two numbers"""
1225
+ return a + b
1226
+
1227
+
1228
+ # Define a collection of tools used by the model
1229
+ tools = [add_numbers]
1230
+
1231
+
1232
+ @app.entrypoint
1233
+ def invoke(payload, context):
1234
+ log.info("Invoking Agent.....")
1235
+
1236
+ # Define the Agent with Tools
1237
+ agent = Agent(
1238
+ role="Question Answering Assistant",
1239
+ goal="Answer the users questions",
1240
+ backstory="Always eager to answer any questions",
1241
+ llm=load_model(),
1242
+ tools=tools,
1243
+ )
1244
+
1245
+ # Define the Task
1246
+ task = Task(
1247
+ agent=agent,
1248
+ description="Answer the users question: {prompt}",
1249
+ expected_output="An answer to the users question",
1250
+ )
1251
+
1252
+ # Create the Crew
1253
+ crew = Crew(agents=[agent], tasks=[task], process=Process.sequential)
1254
+
1255
+ # Process the user prompt
1256
+ prompt = payload.get("prompt", "What can you help me with?")
1257
+
1258
+ # Run the crew
1259
+ result = crew.kickoff(inputs={"prompt": prompt})
1260
+
1261
+ # Return result
1262
+ return {"result": result.raw}
1263
+
1264
+
1265
+ if __name__ == "__main__":
1266
+ app.run()
1267
+ "
1268
+ `;
1269
+
1270
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/crewai/base/model/load.py should match snapshot 1`] = `
1271
+ "{{#if (eq modelProvider "Bedrock")}}
1272
+ from crewai import LLM
1273
+
1274
+ # Uses global inference profile for Claude Sonnet 4.5
1275
+ # https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-support.html
1276
+ MODEL_ID = "bedrock/global.anthropic.claude-sonnet-4-5-20250929-v1:0"
1277
+
1278
+
1279
+ def load_model() -> LLM:
1280
+ """Get Bedrock model client using IAM credentials."""
1281
+ return LLM(model=MODEL_ID)
1282
+ {{/if}}
1283
+ {{#if (eq modelProvider "Anthropic")}}
1284
+ import os
1285
+ from crewai import LLM
1286
+ from bedrock_agentcore.identity.auth import requires_api_key
1287
+
1288
+ IDENTITY_PROVIDER_NAME = "{{identityProviders.[0].name}}"
1289
+ IDENTITY_ENV_VAR = "{{identityProviders.[0].envVarName}}"
1290
+
1291
+
1292
+ @requires_api_key(provider_name=IDENTITY_PROVIDER_NAME)
1293
+ def _agentcore_identity_api_key_provider(api_key: str) -> str:
1294
+ """Fetch API key from AgentCore Identity."""
1295
+ return api_key
1296
+
1297
+
1298
+ def _get_api_key() -> str:
1299
+ """
1300
+ Uses AgentCore Identity for API key management in deployed environments.
1301
+ For local development, run via 'agentcore dev' which loads agentcore/.env.
1302
+ """
1303
+ if os.getenv("LOCAL_DEV") == "1":
1304
+ api_key = os.getenv(IDENTITY_ENV_VAR)
1305
+ if not api_key:
1306
+ raise RuntimeError(
1307
+ f"{IDENTITY_ENV_VAR} not found. Add {IDENTITY_ENV_VAR}=your-key to .env.local"
1308
+ )
1309
+ return api_key
1310
+ return _agentcore_identity_api_key_provider()
1311
+
1312
+
1313
+ def load_model() -> LLM:
1314
+ """Get authenticated Anthropic model client."""
1315
+ api_key = _get_api_key()
1316
+ # CrewAI requires ANTHROPIC_API_KEY env var (ignores api_key parameter)
1317
+ os.environ["ANTHROPIC_API_KEY"] = api_key
1318
+ return LLM(
1319
+ model="anthropic/claude-sonnet-4-5-20250929",
1320
+ api_key=api_key,
1321
+ max_tokens=4096
1322
+ )
1323
+ {{/if}}
1324
+ {{#if (eq modelProvider "OpenAI")}}
1325
+ import os
1326
+ from crewai import LLM
1327
+ from bedrock_agentcore.identity.auth import requires_api_key
1328
+
1329
+ IDENTITY_PROVIDER_NAME = "{{identityProviders.[0].name}}"
1330
+ IDENTITY_ENV_VAR = "{{identityProviders.[0].envVarName}}"
1331
+
1332
+
1333
+ @requires_api_key(provider_name=IDENTITY_PROVIDER_NAME)
1334
+ def _agentcore_identity_api_key_provider(api_key: str) -> str:
1335
+ """Fetch API key from AgentCore Identity."""
1336
+ return api_key
1337
+
1338
+
1339
+ def _get_api_key() -> str:
1340
+ """
1341
+ Uses AgentCore Identity for API key management in deployed environments.
1342
+ For local development, run via 'agentcore dev' which loads agentcore/.env.
1343
+ """
1344
+ if os.getenv("LOCAL_DEV") == "1":
1345
+ api_key = os.getenv(IDENTITY_ENV_VAR)
1346
+ if not api_key:
1347
+ raise RuntimeError(
1348
+ f"{IDENTITY_ENV_VAR} not found. Add {IDENTITY_ENV_VAR}=your-key to .env.local"
1349
+ )
1350
+ return api_key
1351
+ return _agentcore_identity_api_key_provider()
1352
+
1353
+
1354
+ def load_model() -> LLM:
1355
+ """Get authenticated OpenAI model client."""
1356
+ api_key = _get_api_key()
1357
+ # CrewAI requires OPENAI_API_KEY env var (ignores api_key parameter)
1358
+ os.environ["OPENAI_API_KEY"] = api_key
1359
+ return LLM(
1360
+ model="openai/gpt-4o",
1361
+ api_key=api_key
1362
+ )
1363
+ {{/if}}
1364
+ {{#if (eq modelProvider "Gemini")}}
1365
+ import os
1366
+ from crewai import LLM
1367
+ from bedrock_agentcore.identity.auth import requires_api_key
1368
+
1369
+ IDENTITY_PROVIDER_NAME = "{{identityProviders.[0].name}}"
1370
+ IDENTITY_ENV_VAR = "{{identityProviders.[0].envVarName}}"
1371
+
1372
+
1373
+ @requires_api_key(provider_name=IDENTITY_PROVIDER_NAME)
1374
+ def _agentcore_identity_api_key_provider(api_key: str) -> str:
1375
+ """Fetch API key from AgentCore Identity."""
1376
+ return api_key
1377
+
1378
+
1379
+ def _get_api_key() -> str:
1380
+ """
1381
+ Uses AgentCore Identity for API key management in deployed environments.
1382
+ For local development, run via 'agentcore dev' which loads agentcore/.env.
1383
+ """
1384
+ if os.getenv("LOCAL_DEV") == "1":
1385
+ api_key = os.getenv(IDENTITY_ENV_VAR)
1386
+ if not api_key:
1387
+ raise RuntimeError(
1388
+ f"{IDENTITY_ENV_VAR} not found. Add {IDENTITY_ENV_VAR}=your-key to .env.local"
1389
+ )
1390
+ return api_key
1391
+ return _agentcore_identity_api_key_provider()
1392
+
1393
+
1394
+ def load_model() -> LLM:
1395
+ """Get authenticated Gemini model client."""
1396
+ api_key = _get_api_key()
1397
+ # CrewAI requires GEMINI_API_KEY env var (ignores api_key parameter)
1398
+ os.environ["GEMINI_API_KEY"] = api_key
1399
+ return LLM(
1400
+ model="gemini/gemini-2.0-flash",
1401
+ api_key=api_key
1402
+ )
1403
+ {{/if}}
1404
+ "
1405
+ `;
1406
+
1407
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/crewai/base/pyproject.toml should match snapshot 1`] = `
1408
+ "[build-system]
1409
+ requires = ["hatchling"]
1410
+ build-backend = "hatchling.build"
1411
+
1412
+ [project]
1413
+ name = "{{ name }}"
1414
+ version = "0.1.0"
1415
+ description = "AgentCore Runtime Application using CrewAI SDK"
1416
+ readme = "README.md"
1417
+ requires-python = ">=3.11"
1418
+ dependencies = [
1419
+ "opentelemetry-distro",
1420
+ "opentelemetry-exporter-otlp",
1421
+ "bedrock-agentcore >= 1.0.3",
1422
+ "botocore[crt] >= 1.35.0",
1423
+ "python-dotenv >= 1.0.1",
1424
+ {{#if (eq modelProvider "Bedrock")}}
1425
+ "crewai[tools,bedrock] >= 1.3.0",
1426
+ {{/if}}
1427
+ {{#if (eq modelProvider "Anthropic")}}
1428
+ "crewai[tools,anthropic] >= 1.3.0",
1429
+ {{/if}}
1430
+ {{#if (eq modelProvider "OpenAI")}}
1431
+ "crewai[tools,openai] >= 1.3.0",
1432
+ {{/if}}
1433
+ {{#if (eq modelProvider "Gemini")}}
1434
+ "crewai[tools,google-genai] >= 1.3.0",
1435
+ {{/if}}
1436
+ ]
1437
+
1438
+ [tool.hatch.build.targets.wheel]
1439
+ packages = ["."]
1440
+ "
1441
+ `;
1442
+
1443
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/googleadk/base/README.md should match snapshot 1`] = `
1444
+ "This is a project generated by the agentcore create CLI tool!
1445
+
1446
+ # Layout
1447
+
1448
+ There is one directory with generated application code, \`src/\` . At the root, there is a \`.gitignore\` file, a
1449
+ \`.agentcore\` folder which represents the configurations and state associated with this project. Other \`agentcore\`
1450
+ commands like \`deploy\`, \`dev\`, and \`invoke\` rely on the configuration stored here.
1451
+
1452
+ ## src/
1453
+
1454
+ The main entrypoint to your app is defined in \`src/main.py\`. Using the AgentCore SDK \`@app.entrypoint\` decorator, this
1455
+ file defines a Starlette ASGI app with the Google ADK framework running within.
1456
+
1457
+ \`src/model/load.py\` instantiates your chosen model provider (Gemini).
1458
+
1459
+ ## Environment Variables
1460
+
1461
+ | Variable | Required | Description |
1462
+ | --------------------------- | -------- | ---------------------------------------------------------------- |
1463
+ | \`AGENTCORE_IDENTITY_GEMINI\` | Yes | Gemini API key (local) or Identity provider name (deployed) |
1464
+ | \`LOCAL_DEV\` | No | Set to \`1\` to use \`agentcore/.env\` instead of AgentCore Identity |
1465
+
1466
+ # Developing locally
1467
+
1468
+ If installation was successful, a virtual environment is already created with dependencies installed.
1469
+
1470
+ Run \`source .venv/bin/activate\` before developing.
1471
+
1472
+ \`agentcore dev\` will start a local server on 0.0.0.0:8080.
1473
+
1474
+ In a new terminal, you can invoke that server with:
1475
+
1476
+ \`agentcore invoke --dev "What can you do"\`
1477
+
1478
+ # Deployment
1479
+
1480
+ After providing credentials, \`agentcore deploy\` will deploy your project into Amazon Bedrock AgentCore.
1481
+
1482
+ Use \`agentcore invoke\` to invoke your deployed agent.
1483
+ "
1484
+ `;
1485
+
1486
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/googleadk/base/gitignore.template should match snapshot 1`] = `
1487
+ "# Environment variables
1488
+ .env
1489
+
1490
+ # Python
1491
+ __pycache__/
1492
+ *.py[cod]
1493
+ *$py.class
1494
+ *.so
1495
+ .Python
1496
+ build/
1497
+ develop-eggs/
1498
+ dist/
1499
+ downloads/
1500
+ eggs/
1501
+ .eggs/
1502
+ lib/
1503
+ lib64/
1504
+ parts/
1505
+ sdist/
1506
+ var/
1507
+ wheels/
1508
+ *.egg-info/
1509
+ .installed.cfg
1510
+ *.egg
1511
+
1512
+ # Virtual environments
1513
+ venv/
1514
+ ENV/
1515
+ env/
1516
+
1517
+ # IDE
1518
+ .vscode/
1519
+ .idea/
1520
+ *.swp
1521
+ *.swo
1522
+ *~
1523
+
1524
+ # OS
1525
+ .DS_Store
1526
+ Thumbs.db
1527
+ "
1528
+ `;
1529
+
1530
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/googleadk/base/main.py should match snapshot 1`] = `
1531
+ "import os
1532
+ from google.adk.agents import Agent
1533
+ from google.adk.runners import Runner
1534
+ from google.adk.sessions import InMemorySessionService
1535
+ from google.genai import types
1536
+ from bedrock_agentcore.runtime import BedrockAgentCoreApp
1537
+ from model.load import load_model
1538
+ from mcp_client.client import get_streamable_http_mcp_client
1539
+
1540
+ app = BedrockAgentCoreApp()
1541
+ log = app.logger
1542
+
1543
+ APP_NAME = "{{ name }}"
1544
+
1545
+ # https://google.github.io/adk-docs/agents/models/
1546
+ MODEL_ID = "gemini-2.5-flash"
1547
+
1548
+
1549
+ # Define a simple function tool
1550
+ def add_numbers(a: int, b: int) -> int:
1551
+ """Return the sum of two numbers"""
1552
+ return a + b
1553
+
1554
+
1555
+ # Set environment variables for model authentication
1556
+ load_model()
1557
+
1558
+ # Get MCP Toolset
1559
+ mcp_toolset = [get_streamable_http_mcp_client()]
1560
+
1561
+ # Agent Definition
1562
+ agent = Agent(
1563
+ model=MODEL_ID,
1564
+ name="{{ name }}",
1565
+ description="Agent to answer questions",
1566
+ instruction="I can answer your questions using the knowledge I have!",
1567
+ tools=mcp_toolset + [add_numbers],
1568
+ )
1569
+
1570
+
1571
+ # Session and Runner
1572
+ async def setup_session_and_runner(user_id, session_id):
1573
+ session_service = InMemorySessionService()
1574
+ session = await session_service.create_session(
1575
+ app_name=APP_NAME, user_id=user_id, session_id=session_id
1576
+ )
1577
+ runner = Runner(agent=agent, app_name=APP_NAME, session_service=session_service)
1578
+ return session, runner
1579
+
1580
+
1581
+ # Agent Interaction
1582
+ async def call_agent_async(query, user_id, session_id):
1583
+ content = types.Content(role="user", parts=[types.Part(text=query)])
1584
+ session, runner = await setup_session_and_runner(user_id, session_id)
1585
+ events = runner.run_async(
1586
+ user_id=user_id, session_id=session.id, new_message=content
1587
+ )
1588
+
1589
+ final_response = None
1590
+ async for event in events:
1591
+ if event.is_final_response():
1592
+ final_response = event.content.parts[0].text
1593
+
1594
+ return final_response
1595
+
1596
+
1597
+ @app.entrypoint
1598
+ async def invoke(payload, context):
1599
+ log.info("Invoking Agent.....")
1600
+
1601
+ # Process the user prompt
1602
+ prompt = payload.get("prompt", "What can you help me with?")
1603
+ session_id = getattr(context, "session_id", "default_session")
1604
+ user_id = payload.get("user_id", "default_user")
1605
+
1606
+ # Run the agent
1607
+ result = await call_agent_async(prompt, user_id, session_id)
1608
+
1609
+ # Return result
1610
+ return {"result": result}
1611
+
1612
+
1613
+ if __name__ == "__main__":
1614
+ app.run()
1615
+ "
1616
+ `;
1617
+
1618
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/googleadk/base/mcp_client/client.py should match snapshot 1`] = `
1619
+ "from google.adk.tools.mcp_tool.mcp_toolset import MCPToolset
1620
+ from google.adk.tools.mcp_tool.mcp_session_manager import StreamableHTTPConnectionParams
1621
+
1622
+ # ExaAI provides information about code through web searches, crawling and code context searches through their platform. Requires no authentication
1623
+ EXAMPLE_MCP_ENDPOINT = "https://mcp.exa.ai/mcp"
1624
+
1625
+
1626
+ def get_streamable_http_mcp_client() -> MCPToolset:
1627
+ """
1628
+ Returns an MCP Toolset compatible with Google ADK.
1629
+ """
1630
+ # to use an MCP server that supports bearer authentication, add headers={"Authorization": f"Bearer {access_token}"}
1631
+ return MCPToolset(
1632
+ connection_params=StreamableHTTPConnectionParams(url=EXAMPLE_MCP_ENDPOINT)
1633
+ )
1634
+ "
1635
+ `;
1636
+
1637
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/googleadk/base/model/load.py should match snapshot 1`] = `
1638
+ "import os
1639
+ from bedrock_agentcore.identity.auth import requires_api_key
1640
+
1641
+ IDENTITY_PROVIDER_NAME = "{{identityProviders.[0].name}}"
1642
+ IDENTITY_ENV_VAR = "{{identityProviders.[0].envVarName}}"
1643
+
1644
+
1645
+ @requires_api_key(provider_name=IDENTITY_PROVIDER_NAME)
1646
+ def _agentcore_identity_api_key_provider(api_key: str) -> str:
1647
+ """Fetch API key from AgentCore Identity."""
1648
+ return api_key
1649
+
1650
+
1651
+ def _get_api_key() -> str:
1652
+ """
1653
+ Uses AgentCore Identity for API key management in deployed environments.
1654
+ For local development, run via 'agentcore dev' which loads agentcore/.env.
1655
+ """
1656
+ if os.getenv("LOCAL_DEV") == "1":
1657
+ api_key = os.getenv(IDENTITY_ENV_VAR)
1658
+ if not api_key:
1659
+ raise RuntimeError(
1660
+ f"{IDENTITY_ENV_VAR} not found. Add {IDENTITY_ENV_VAR}=your-key to .env.local"
1661
+ )
1662
+ return api_key
1663
+ return _agentcore_identity_api_key_provider()
1664
+
1665
+
1666
+ def load_model() -> None:
1667
+ """
1668
+ Set up Gemini API key authentication.
1669
+ Uses AgentCore Identity for API key management in deployed environments,
1670
+ and falls back to .env file for local development.
1671
+ Sets the GOOGLE_API_KEY environment variable for the Google ADK.
1672
+ """
1673
+ api_key = _get_api_key()
1674
+ # Use Google AI Studios API Key Authentication.
1675
+ # https://google.github.io/adk-docs/agents/models/#google-ai-studio
1676
+ os.environ["GOOGLE_API_KEY"] = api_key
1677
+ # Set to TRUE is using Google Vertex AI, Set to FALSE for Google AI Studio
1678
+ os.environ["GOOGLE_GENAI_USE_VERTEXAI"] = "FALSE"
1679
+ "
1680
+ `;
1681
+
1682
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/googleadk/base/pyproject.toml should match snapshot 1`] = `
1683
+ "[build-system]
1684
+ requires = ["hatchling"]
1685
+ build-backend = "hatchling.build"
1686
+
1687
+ [project]
1688
+ name = "{{ name }}"
1689
+ version = "0.1.0"
1690
+ description = "AgentCore Runtime Application using Google ADK"
1691
+ readme = "README.md"
1692
+ requires-python = ">=3.10"
1693
+ dependencies = [
1694
+ "opentelemetry-distro",
1695
+ "opentelemetry-exporter-otlp",
1696
+ "google-adk >= 1.17.0",
1697
+ "bedrock-agentcore >= 1.0.3",
1698
+ "botocore[crt] >= 1.35.0",
1699
+ "python-dotenv >= 1.0.1",
1700
+ ]
1701
+
1702
+ [tool.hatch.build.targets.wheel]
1703
+ packages = ["."]
1704
+ "
1705
+ `;
1706
+
1707
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/langchain_langgraph/base/README.md should match snapshot 1`] = `
1708
+ "This is a project generated by the agentcore create CLI tool!
1709
+
1710
+ # Layout
1711
+
1712
+ There is one directory with generated application code, \`src/\` . At the root, there is a \`.gitignore\` file, a
1713
+ \`.agentcore\` folder which represents the configurations and state associated with this project. Other \`agentcore\`
1714
+ commands like \`deploy\`, \`dev\`, and \`invoke\` rely on the configuration stored here.
1715
+
1716
+ ## src/
1717
+
1718
+ The main entrypoint to your app is defined in \`src/main.py\`. Using the AgentCore SDK \`@app.entrypoint\` decorator, this
1719
+ file defines a Starlette ASGI app with the LangChain/LangGraph framework running within.
1720
+
1721
+ \`src/model/load.py\` instantiates your chosen model provider.
1722
+
1723
+ ## Environment Variables
1724
+
1725
+ | Variable | Required | Description |
1726
+ | ------------------------------ | --------------- | ---------------------------------------------------------------- |
1727
+ | \`AGENTCORE_IDENTITY_OPENAI\` | Yes (OpenAI) | OpenAI API key (local) or Identity provider name (deployed) |
1728
+ | \`AGENTCORE_IDENTITY_ANTHROPIC\` | Yes (Anthropic) | Anthropic API key (local) or Identity provider name (deployed) |
1729
+ | \`AGENTCORE_IDENTITY_GEMINI\` | Yes (Gemini) | Gemini API key (local) or Identity provider name (deployed) |
1730
+ | \`LOCAL_DEV\` | No | Set to \`1\` to use \`agentcore/.env\` instead of AgentCore Identity |
1731
+
1732
+ # Developing locally
1733
+
1734
+ If installation was successful, a virtual environment is already created with dependencies installed.
1735
+
1736
+ Run \`source .venv/bin/activate\` before developing.
1737
+
1738
+ \`agentcore dev\` will start a local server on 0.0.0.0:8080.
1739
+
1740
+ In a new terminal, you can invoke that server with:
1741
+
1742
+ \`agentcore invoke --dev "What can you do"\`
1743
+
1744
+ # Deployment
1745
+
1746
+ After providing credentials, \`agentcore deploy\` will deploy your project into Amazon Bedrock AgentCore.
1747
+
1748
+ Use \`agentcore invoke\` to invoke your deployed agent.
1749
+ "
1750
+ `;
1751
+
1752
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/langchain_langgraph/base/gitignore.template should match snapshot 1`] = `
1753
+ "# Environment variables
1754
+ .env
1755
+
1756
+ # Python
1757
+ __pycache__/
1758
+ *.py[cod]
1759
+ *$py.class
1760
+ *.so
1761
+ .Python
1762
+ build/
1763
+ develop-eggs/
1764
+ dist/
1765
+ downloads/
1766
+ eggs/
1767
+ .eggs/
1768
+ lib/
1769
+ lib64/
1770
+ parts/
1771
+ sdist/
1772
+ var/
1773
+ wheels/
1774
+ *.egg-info/
1775
+ .installed.cfg
1776
+ *.egg
1777
+
1778
+ # Virtual environments
1779
+ venv/
1780
+ ENV/
1781
+ env/
1782
+
1783
+ # IDE
1784
+ .vscode/
1785
+ .idea/
1786
+ *.swp
1787
+ *.swo
1788
+ *~
1789
+
1790
+ # OS
1791
+ .DS_Store
1792
+ Thumbs.db
1793
+ "
1794
+ `;
1795
+
1796
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/langchain_langgraph/base/main.py should match snapshot 1`] = `
1797
+ "import os
1798
+ from langchain_core.messages import HumanMessage
1799
+ from langgraph.prebuilt import create_react_agent
1800
+ from langchain.tools import tool
1801
+ from bedrock_agentcore.runtime import BedrockAgentCoreApp
1802
+ from model.load import load_model
1803
+ from mcp_client.client import get_streamable_http_mcp_client
1804
+
1805
+ app = BedrockAgentCoreApp()
1806
+ log = app.logger
1807
+
1808
+ # Instantiate model
1809
+ llm = load_model()
1810
+
1811
+
1812
+ # Define a simple function tool
1813
+ @tool
1814
+ def add_numbers(a: int, b: int) -> int:
1815
+ """Return the sum of two numbers"""
1816
+ return a + b
1817
+
1818
+
1819
+ # Define a collection of tools used by the model
1820
+ tools = [add_numbers]
1821
+
1822
+
1823
+ @app.entrypoint
1824
+ async def invoke(payload, context):
1825
+ log.info("Invoking Agent.....")
1826
+
1827
+ # Get MCP Client
1828
+ mcp_client = get_streamable_http_mcp_client()
1829
+
1830
+ # Load MCP Tools
1831
+ mcp_tools = await mcp_client.get_tools()
1832
+
1833
+ # Define the agent using create_react_agent
1834
+ graph = create_react_agent(llm, tools=mcp_tools + tools)
1835
+
1836
+ # Process the user prompt
1837
+ prompt = payload.get("prompt", "What can you help me with?")
1838
+
1839
+ # Run the agent
1840
+ result = await graph.ainvoke({"messages": [HumanMessage(content=prompt)]})
1841
+
1842
+ # Return result
1843
+ return {"result": result["messages"][-1].content}
1844
+
1845
+
1846
+ if __name__ == "__main__":
1847
+ app.run()
1848
+ "
1849
+ `;
1850
+
1851
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/langchain_langgraph/base/mcp_client/client.py should match snapshot 1`] = `
1852
+ "from langchain_mcp_adapters.client import MultiServerMCPClient
1853
+
1854
+ # ExaAI provides information about code through web searches, crawling and code context searches through their platform. Requires no authentication
1855
+ EXAMPLE_MCP_ENDPOINT = "https://mcp.exa.ai/mcp"
1856
+
1857
+
1858
+ def get_streamable_http_mcp_client() -> MultiServerMCPClient:
1859
+ """
1860
+ Returns an MCP Client compatible with LangChain/LangGraph.
1861
+ """
1862
+ # to use an MCP server that supports bearer authentication, add headers={"Authorization": f"Bearer {access_token}"}
1863
+ return MultiServerMCPClient(
1864
+ {
1865
+ "agentcore_gateway": {
1866
+ "transport": "streamable_http",
1867
+ "url": EXAMPLE_MCP_ENDPOINT,
1868
+ }
1869
+ }
1870
+ )
1871
+ "
1872
+ `;
1873
+
1874
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/langchain_langgraph/base/model/load.py should match snapshot 1`] = `
1875
+ "{{#if (eq modelProvider "Bedrock")}}
1876
+ from langchain_aws import ChatBedrock
1877
+
1878
+ # Uses global inference profile for Claude Sonnet 4.5
1879
+ # https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-support.html
1880
+ MODEL_ID = "global.anthropic.claude-sonnet-4-5-20250929-v1:0"
1881
+
1882
+
1883
+ def load_model() -> ChatBedrock:
1884
+ """Get Bedrock model client using IAM credentials."""
1885
+ return ChatBedrock(model_id=MODEL_ID)
1886
+ {{/if}}
1887
+ {{#if (eq modelProvider "Anthropic")}}
1888
+ import os
1889
+ from langchain_anthropic import ChatAnthropic
1890
+ from bedrock_agentcore.identity.auth import requires_api_key
1891
+
1892
+ IDENTITY_PROVIDER_NAME = "{{identityProviders.[0].name}}"
1893
+ IDENTITY_ENV_VAR = "{{identityProviders.[0].envVarName}}"
1894
+
1895
+
1896
+ @requires_api_key(provider_name=IDENTITY_PROVIDER_NAME)
1897
+ def _agentcore_identity_api_key_provider(api_key: str) -> str:
1898
+ """Fetch API key from AgentCore Identity."""
1899
+ return api_key
1900
+
1901
+
1902
+ def _get_api_key() -> str:
1903
+ """
1904
+ Uses AgentCore Identity for API key management in deployed environments.
1905
+ For local development, run via 'agentcore dev' which loads agentcore/.env.
1906
+ """
1907
+ if os.getenv("LOCAL_DEV") == "1":
1908
+ api_key = os.getenv(IDENTITY_ENV_VAR)
1909
+ if not api_key:
1910
+ raise RuntimeError(
1911
+ f"{IDENTITY_ENV_VAR} not found. Add {IDENTITY_ENV_VAR}=your-key to .env.local"
1912
+ )
1913
+ return api_key
1914
+ return _agentcore_identity_api_key_provider()
1915
+
1916
+
1917
+ def load_model() -> ChatAnthropic:
1918
+ """Get authenticated Anthropic model client."""
1919
+ return ChatAnthropic(
1920
+ model="claude-sonnet-4-5-20250929",
1921
+ api_key=_get_api_key()
1922
+ )
1923
+ {{/if}}
1924
+ {{#if (eq modelProvider "OpenAI")}}
1925
+ import os
1926
+ from langchain_openai import ChatOpenAI
1927
+ from bedrock_agentcore.identity.auth import requires_api_key
1928
+
1929
+ IDENTITY_PROVIDER_NAME = "{{identityProviders.[0].name}}"
1930
+ IDENTITY_ENV_VAR = "{{identityProviders.[0].envVarName}}"
1931
+
1932
+
1933
+ @requires_api_key(provider_name=IDENTITY_PROVIDER_NAME)
1934
+ def _agentcore_identity_api_key_provider(api_key: str) -> str:
1935
+ """Fetch API key from AgentCore Identity."""
1936
+ return api_key
1937
+
1938
+
1939
+ def _get_api_key() -> str:
1940
+ """
1941
+ Uses AgentCore Identity for API key management in deployed environments.
1942
+ For local development, run via 'agentcore dev' which loads agentcore/.env.
1943
+ """
1944
+ if os.getenv("LOCAL_DEV") == "1":
1945
+ api_key = os.getenv(IDENTITY_ENV_VAR)
1946
+ if not api_key:
1947
+ raise RuntimeError(
1948
+ f"{IDENTITY_ENV_VAR} not found. Add {IDENTITY_ENV_VAR}=your-key to .env.local"
1949
+ )
1950
+ return api_key
1951
+ return _agentcore_identity_api_key_provider()
1952
+
1953
+
1954
+ def load_model() -> ChatOpenAI:
1955
+ """Get authenticated OpenAI model client."""
1956
+ return ChatOpenAI(
1957
+ model="gpt-4o",
1958
+ api_key=_get_api_key()
1959
+ )
1960
+ {{/if}}
1961
+ {{#if (eq modelProvider "Gemini")}}
1962
+ import os
1963
+ from langchain_google_genai import ChatGoogleGenerativeAI
1964
+ from bedrock_agentcore.identity.auth import requires_api_key
1965
+
1966
+ IDENTITY_PROVIDER_NAME = "{{identityProviders.[0].name}}"
1967
+ IDENTITY_ENV_VAR = "{{identityProviders.[0].envVarName}}"
1968
+
1969
+
1970
+ @requires_api_key(provider_name=IDENTITY_PROVIDER_NAME)
1971
+ def _agentcore_identity_api_key_provider(api_key: str) -> str:
1972
+ """Fetch API key from AgentCore Identity."""
1973
+ return api_key
1974
+
1975
+
1976
+ def _get_api_key() -> str:
1977
+ """
1978
+ Uses AgentCore Identity for API key management in deployed environments.
1979
+ For local development, run via 'agentcore dev' which loads agentcore/.env.
1980
+ """
1981
+ if os.getenv("LOCAL_DEV") == "1":
1982
+ api_key = os.getenv(IDENTITY_ENV_VAR)
1983
+ if not api_key:
1984
+ raise RuntimeError(
1985
+ f"{IDENTITY_ENV_VAR} not found. Add {IDENTITY_ENV_VAR}=your-key to .env.local"
1986
+ )
1987
+ return api_key
1988
+ return _agentcore_identity_api_key_provider()
1989
+
1990
+
1991
+ def load_model() -> ChatGoogleGenerativeAI:
1992
+ """Get authenticated Gemini model client."""
1993
+ return ChatGoogleGenerativeAI(
1994
+ model="gemini-2.0-flash",
1995
+ api_key=_get_api_key()
1996
+ )
1997
+ {{/if}}
1998
+ "
1999
+ `;
2000
+
2001
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/langchain_langgraph/base/pyproject.toml should match snapshot 1`] = `
2002
+ "[build-system]
2003
+ requires = ["hatchling"]
2004
+ build-backend = "hatchling.build"
2005
+
2006
+ [project]
2007
+ name = "{{ name }}"
2008
+ version = "0.1.0"
2009
+ description = "AgentCore Runtime Application using LangChain/LangGraph"
2010
+ readme = "README.md"
2011
+ requires-python = ">=3.10"
2012
+ dependencies = [
2013
+ "opentelemetry-distro",
2014
+ "opentelemetry-exporter-otlp",
2015
+ "langgraph >= 1.0.2",
2016
+ "mcp >= 1.19.0",
2017
+ "langchain-mcp-adapters >= 0.1.11",
2018
+ "langchain >= 1.0.3",
2019
+ "tiktoken == 0.11.0",
2020
+ "bedrock-agentcore >= 1.0.3",
2021
+ "botocore[crt] >= 1.35.0",
2022
+ "python-dotenv >= 1.0.1",
2023
+ {{#if (eq modelProvider "Bedrock")}}
2024
+ "langchain-aws >= 1.0.0",
2025
+ {{/if}}
2026
+ {{#if (eq modelProvider "Anthropic")}}
2027
+ "langchain-anthropic >= 1.1.0",
2028
+ {{/if}}
2029
+ {{#if (eq modelProvider "OpenAI")}}
2030
+ "langchain-openai >= 1.0.3",
2031
+ {{/if}}
2032
+ {{#if (eq modelProvider "Gemini")}}
2033
+ "langchain-google-genai >= 3.0.3",
2034
+ {{/if}}
2035
+ ]
2036
+
2037
+ [tool.hatch.build.targets.wheel]
2038
+ packages = ["."]
2039
+ "
2040
+ `;
2041
+
2042
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/openaiagents/base/README.md should match snapshot 1`] = `
2043
+ "This is a project generated by the agentcore create CLI tool!
2044
+
2045
+ # Layout
2046
+
2047
+ There is one directory with generated application code, \`src/\` . At the root, there is a \`.gitignore\` file, a
2048
+ \`.agentcore\` folder which represents the configurations and state associated with this project. Other \`agentcore\`
2049
+ commands like \`deploy\`, \`dev\`, and \`invoke\` rely on the configuration stored here.
2050
+
2051
+ ## src/
2052
+
2053
+ The main entrypoint to your app is defined in \`src/main.py\`. Using the AgentCore SDK \`@app.entrypoint\` decorator, this
2054
+ file defines a Starlette ASGI app with the OpenAI Agents SDK framework running within.
2055
+
2056
+ \`src/model/load.py\` instantiates your chosen model provider (OpenAI).
2057
+
2058
+ ## Environment Variables
2059
+
2060
+ | Variable | Required | Description |
2061
+ | --------------------------- | -------- | ---------------------------------------------------------------- |
2062
+ | \`AGENTCORE_IDENTITY_OPENAI\` | Yes | OpenAI API key (local) or Identity provider name (deployed) |
2063
+ | \`LOCAL_DEV\` | No | Set to \`1\` to use \`agentcore/.env\` instead of AgentCore Identity |
2064
+
2065
+ # Developing locally
2066
+
2067
+ If installation was successful, a virtual environment is already created with dependencies installed.
2068
+
2069
+ Run \`source .venv/bin/activate\` before developing.
2070
+
2071
+ \`agentcore dev\` will start a local server on 0.0.0.0:8080.
2072
+
2073
+ In a new terminal, you can invoke that server with:
2074
+
2075
+ \`agentcore invoke --dev "What can you do"\`
2076
+
2077
+ # Deployment
2078
+
2079
+ After providing credentials, \`agentcore deploy\` will deploy your project into Amazon Bedrock AgentCore.
2080
+
2081
+ Use \`agentcore invoke\` to invoke your deployed agent.
2082
+ "
2083
+ `;
2084
+
2085
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/openaiagents/base/gitignore.template should match snapshot 1`] = `
2086
+ "# Environment variables
2087
+ .env
2088
+
2089
+ # Python
2090
+ __pycache__/
2091
+ *.py[cod]
2092
+ *$py.class
2093
+ *.so
2094
+ .Python
2095
+ build/
2096
+ develop-eggs/
2097
+ dist/
2098
+ downloads/
2099
+ eggs/
2100
+ .eggs/
2101
+ lib/
2102
+ lib64/
2103
+ parts/
2104
+ sdist/
2105
+ var/
2106
+ wheels/
2107
+ *.egg-info/
2108
+ .installed.cfg
2109
+ *.egg
2110
+
2111
+ # Virtual environments
2112
+ venv/
2113
+ ENV/
2114
+ env/
2115
+
2116
+ # IDE
2117
+ .vscode/
2118
+ .idea/
2119
+ *.swp
2120
+ *.swo
2121
+ *~
2122
+
2123
+ # OS
2124
+ .DS_Store
2125
+ Thumbs.db
2126
+ "
2127
+ `;
2128
+
2129
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/openaiagents/base/main.py should match snapshot 1`] = `
2130
+ "import os
2131
+ from agents import Agent, Runner, function_tool
2132
+ from bedrock_agentcore.runtime import BedrockAgentCoreApp
2133
+ from model.load import load_model
2134
+ from mcp_client.client import get_streamable_http_mcp_client
2135
+
2136
+ app = BedrockAgentCoreApp()
2137
+ log = app.logger
2138
+
2139
+ # Set environment variables for model authentication
2140
+ load_model()
2141
+
2142
+ # Get MCP Server
2143
+ mcp_server = get_streamable_http_mcp_client()
2144
+
2145
+
2146
+ # Define a simple function tool
2147
+ @function_tool
2148
+ def add_numbers(a: int, b: int) -> int:
2149
+ """Return the sum of two numbers"""
2150
+ return a + b
2151
+
2152
+
2153
+ # Define the agent execution
2154
+ async def main(query):
2155
+ try:
2156
+ async with mcp_server as server:
2157
+ active_servers = [server] if server else []
2158
+ # Currently defaults to GPT-4.1
2159
+ # https://openai.github.io/openai-agents-python/models/
2160
+ agent = Agent(
2161
+ name="{{ name }}", mcp_servers=active_servers, tools=[add_numbers]
2162
+ )
2163
+ result = await Runner.run(agent, query)
2164
+ return result
2165
+ except Exception as e:
2166
+ log.error(f"Error during agent execution: {e}", exc_info=True)
2167
+ raise e
2168
+
2169
+
2170
+ @app.entrypoint
2171
+ async def invoke(payload, context):
2172
+ log.info("Invoking Agent.....")
2173
+
2174
+ # Process the user prompt
2175
+ prompt = payload.get("prompt", "What can you help me with?")
2176
+
2177
+ # Run the agent
2178
+ result = await main(prompt)
2179
+
2180
+ # Return result
2181
+ return {"result": result.final_output}
2182
+
2183
+
2184
+ if __name__ == "__main__":
2185
+ app.run()
2186
+ "
2187
+ `;
2188
+
2189
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/openaiagents/base/mcp_client/client.py should match snapshot 1`] = `
2190
+ "from agents.mcp import MCPServerStreamableHttp
2191
+
2192
+ # ExaAI provides information about code through web searches, crawling and code context searches through their platform. Requires no authentication
2193
+ EXAMPLE_MCP_ENDPOINT = "https://mcp.exa.ai/mcp"
2194
+
2195
+
2196
+ def get_streamable_http_mcp_client() -> MCPServerStreamableHttp:
2197
+ """
2198
+ Returns an MCP Client compatible with OpenAI Agents SDK.
2199
+ """
2200
+ # to use an MCP server that supports bearer authentication, add headers={"Authorization": f"Bearer {access_token}"}
2201
+ return MCPServerStreamableHttp(
2202
+ name="AgentCore Gateway MCP", params={"url": EXAMPLE_MCP_ENDPOINT}
2203
+ )
2204
+ "
2205
+ `;
2206
+
2207
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/openaiagents/base/model/load.py should match snapshot 1`] = `
2208
+ "import os
2209
+ from bedrock_agentcore.identity.auth import requires_api_key
2210
+
2211
+ IDENTITY_PROVIDER_NAME = "{{identityProviders.[0].name}}"
2212
+ IDENTITY_ENV_VAR = "{{identityProviders.[0].envVarName}}"
2213
+
2214
+
2215
+ @requires_api_key(provider_name=IDENTITY_PROVIDER_NAME)
2216
+ def _agentcore_identity_api_key_provider(api_key: str) -> str:
2217
+ """Fetch API key from AgentCore Identity."""
2218
+ return api_key
2219
+
2220
+
2221
+ def _get_api_key() -> str:
2222
+ """
2223
+ Uses AgentCore Identity for API key management in deployed environments.
2224
+ For local development, run via 'agentcore dev' which loads agentcore/.env.
2225
+ """
2226
+ if os.getenv("LOCAL_DEV") == "1":
2227
+ api_key = os.getenv(IDENTITY_ENV_VAR)
2228
+ if not api_key:
2229
+ raise RuntimeError(
2230
+ f"{IDENTITY_ENV_VAR} not found. Add {IDENTITY_ENV_VAR}=your-key to .env.local"
2231
+ )
2232
+ return api_key
2233
+ return _agentcore_identity_api_key_provider()
2234
+
2235
+
2236
+ def load_model() -> None:
2237
+ """
2238
+ Set up OpenAI API key authentication.
2239
+ Uses AgentCore Identity for API key management in deployed environments,
2240
+ and falls back to .env file for local development.
2241
+ Sets the OPENAI_API_KEY environment variable for the OpenAI Agents SDK.
2242
+ """
2243
+ api_key = _get_api_key()
2244
+ os.environ["OPENAI_API_KEY"] = api_key if api_key else ""
2245
+ "
2246
+ `;
2247
+
2248
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/openaiagents/base/pyproject.toml should match snapshot 1`] = `
2249
+ "[build-system]
2250
+ requires = ["hatchling"]
2251
+ build-backend = "hatchling.build"
2252
+
2253
+ [project]
2254
+ name = "{{ name }}"
2255
+ version = "0.1.0"
2256
+ description = "AgentCore Runtime Application using OpenAI Agents SDK"
2257
+ readme = "README.md"
2258
+ requires-python = ">=3.10"
2259
+ dependencies = [
2260
+ "aws-opentelemetry-distro",
2261
+ "openai-agents >= 0.4.2",
2262
+ "bedrock-agentcore >= 1.0.3",
2263
+ "botocore[crt] >= 1.35.0",
2264
+ "python-dotenv >= 1.0.1",
2265
+ ]
2266
+
2267
+ [tool.hatch.build.targets.wheel]
2268
+ packages = ["."]
2269
+ "
2270
+ `;
2271
+
2272
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/strands/base/README.md should match snapshot 1`] = `
2273
+ "This is a project generated by the agentcore create basic CLI tool!
2274
+
2275
+ # Layout
2276
+
2277
+ There is one directory with generated application code, \`src/\` . At the root, there is a \`.gitignore\` file, a
2278
+ \`.agentcore\` folder which represents the configurations and state associated with this project. Other \`agentcore\`
2279
+ commands like \`deploy\`, \`dev\`, and \`invoke\` rely on the configuration stored here.
2280
+
2281
+ ## src/
2282
+
2283
+ The main entrypoint to your app is defined in \`src/main.py\`. Using the AgentCore SDK \`@app.entrypoint\` decorator, this
2284
+ file defines a Starlette ASGI app with the chosen Agent framework SDK running within.
2285
+
2286
+ \`src/model/load.py\` instantiates your chosen model provider.
2287
+
2288
+ ## Environment Variables
2289
+
2290
+ | Variable | Required | Description |
2291
+ | ------------------------------ | --------------- | ---------------------------------------------------------------- |
2292
+ | \`AGENTCORE_IDENTITY_OPENAI\` | Yes (OpenAI) | OpenAI API key (local) or Identity provider name (deployed) |
2293
+ | \`AGENTCORE_IDENTITY_ANTHROPIC\` | Yes (Anthropic) | Anthropic API key (local) or Identity provider name (deployed) |
2294
+ | \`AGENTCORE_IDENTITY_GEMINI\` | Yes (Gemini) | Gemini API key (local) or Identity provider name (deployed) |
2295
+ | \`LOCAL_DEV\` | No | Set to \`1\` to use \`agentcore/.env\` instead of AgentCore Identity |
2296
+
2297
+ # Developing locally
2298
+
2299
+ If installation was successful, a virtual environment is already created with dependencies installed.
2300
+
2301
+ Run \`source .venv/bin/activate\` before developing.
2302
+
2303
+ \`agentcore dev\` will start a local server on 0.0.0.0:8080.
2304
+
2305
+ In a new terminal, you can invoke that server with:
2306
+
2307
+ \`agentcore invoke --dev "What can you do"\`
2308
+
2309
+ # Deployment
2310
+
2311
+ After providing credentials, \`agentcore deploy\` will deploy your project into Amazon Bedrock AgentCore.
2312
+
2313
+ Use \`agentcore invoke\` to invoke your deployed agent.
2314
+ "
2315
+ `;
2316
+
2317
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/strands/base/gitignore.template should match snapshot 1`] = `
2318
+ "# Environment variables
2319
+ .env
2320
+ .env
2321
+
2322
+ # Python
2323
+ __pycache__/
2324
+ *.py[cod]
2325
+ *$py.class
2326
+ *.so
2327
+ .Python
2328
+ build/
2329
+ develop-eggs/
2330
+ dist/
2331
+ downloads/
2332
+ eggs/
2333
+ .eggs/
2334
+ lib/
2335
+ lib64/
2336
+ parts/
2337
+ sdist/
2338
+ var/
2339
+ wheels/
2340
+ *.egg-info/
2341
+ .installed.cfg
2342
+ *.egg
2343
+
2344
+ # Virtual environments
2345
+ venv/
2346
+ ENV/
2347
+ env/
2348
+
2349
+ # IDE
2350
+ .vscode/
2351
+ .idea/
2352
+ *.swp
2353
+ *.swo
2354
+ *~
2355
+
2356
+ # OS
2357
+ .DS_Store
2358
+ Thumbs.db"
2359
+ `;
2360
+
2361
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/strands/base/main.py should match snapshot 1`] = `
2362
+ "from strands import Agent, tool
2363
+ from bedrock_agentcore.runtime import BedrockAgentCoreApp
2364
+ from model.load import load_model
2365
+ from mcp_client.client import get_streamable_http_mcp_client
2366
+ {{#if hasMemory}}
2367
+ from memory.session import get_memory_session_manager
2368
+ {{/if}}
2369
+
2370
+ app = BedrockAgentCoreApp()
2371
+ log = app.logger
2372
+
2373
+ # Define a Streamable HTTP MCP Client
2374
+ mcp_client = get_streamable_http_mcp_client()
2375
+
2376
+ # Define a collection of tools used by the model
2377
+ tools = []
2378
+
2379
+ # Define a simple function tool
2380
+ @tool
2381
+ def add_numbers(a: int, b: int) -> int:
2382
+ """Return the sum of two numbers"""
2383
+ return a+b
2384
+ tools.append(add_numbers)
2385
+
2386
+
2387
+ {{#if hasMemory}}
2388
+ def agent_factory():
2389
+ cache = {}
2390
+ def get_or_create_agent(session_id, user_id):
2391
+ key = f"{session_id}/{user_id}"
2392
+ if key not in cache:
2393
+ # Create an agent for the given session_id and user_id
2394
+ cache[key] = Agent(
2395
+ model=load_model(),
2396
+ session_manager=get_memory_session_manager(session_id, user_id),
2397
+ system_prompt="""
2398
+ You are a helpful assistant. Use tools when appropriate.
2399
+ """,
2400
+ tools=tools+[mcp_client]
2401
+ )
2402
+ return cache[key]
2403
+ return get_or_create_agent
2404
+ get_or_create_agent = agent_factory()
2405
+ {{else}}
2406
+ # Create agent
2407
+ agent = Agent(
2408
+ model=load_model(),
2409
+ system_prompt="""
2410
+ You are a helpful assistant. Use tools when appropriate.
2411
+ """,
2412
+ tools=tools+[mcp_client]
2413
+ )
2414
+ {{/if}}
2415
+
2416
+
2417
+ @app.entrypoint
2418
+ async def invoke(payload, context):
2419
+ log.info("Invoking Agent.....")
2420
+
2421
+ {{#if hasMemory}}
2422
+ session_id = getattr(context, 'session_id', 'default-session')
2423
+ user_id = getattr(context, 'user_id', 'default-user')
2424
+ agent = get_or_create_agent(session_id, user_id)
2425
+
2426
+ {{/if}}
2427
+ # Execute and format response
2428
+ stream = agent.stream_async(payload.get("prompt"))
2429
+
2430
+ async for event in stream:
2431
+ # Handle Text parts of the response
2432
+ if "data" in event and isinstance(event["data"], str):
2433
+ yield event["data"]
2434
+
2435
+
2436
+ if __name__ == "__main__":
2437
+ app.run()
2438
+ "
2439
+ `;
2440
+
2441
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/strands/base/mcp_client/client.py should match snapshot 1`] = `
2442
+ "from mcp.client.streamable_http import streamablehttp_client
2443
+ from strands.tools.mcp.mcp_client import MCPClient
2444
+
2445
+ # ExaAI provides information about code through web searches, crawling and code context searches through their platform. Requires no authentication
2446
+ EXAMPLE_MCP_ENDPOINT = "https://mcp.exa.ai/mcp"
2447
+
2448
+ def get_streamable_http_mcp_client() -> MCPClient:
2449
+ """
2450
+ Returns an MCP Client compatible with Strands
2451
+ """
2452
+ # to use an MCP server that supports bearer authentication, add headers={"Authorization": f"Bearer {access_token}"}
2453
+ return MCPClient(lambda: streamablehttp_client(EXAMPLE_MCP_ENDPOINT))"
2454
+ `;
2455
+
2456
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/strands/base/model/load.py should match snapshot 1`] = `
2457
+ "{{#if (eq modelProvider "Bedrock")}}
2458
+ from strands.models.bedrock import BedrockModel
2459
+
2460
+
2461
+ def load_model() -> BedrockModel:
2462
+ """Get Bedrock model client using IAM credentials."""
2463
+ return BedrockModel(model_id="global.anthropic.claude-sonnet-4-5-20250929-v1:0")
2464
+ {{/if}}
2465
+ {{#if (eq modelProvider "Anthropic")}}
2466
+ import os
2467
+
2468
+ from strands.models.anthropic import AnthropicModel
2469
+ from bedrock_agentcore.identity.auth import requires_api_key
2470
+
2471
+ IDENTITY_PROVIDER_NAME = "{{identityProviders.[0].name}}"
2472
+ IDENTITY_ENV_VAR = "{{identityProviders.[0].envVarName}}"
2473
+
2474
+
2475
+ @requires_api_key(provider_name=IDENTITY_PROVIDER_NAME)
2476
+ def _agentcore_identity_api_key_provider(api_key: str) -> str:
2477
+ """Fetch API key from AgentCore Identity."""
2478
+ return api_key
2479
+
2480
+
2481
+ def _get_api_key() -> str:
2482
+ """
2483
+ Uses AgentCore Identity for API key management in deployed environments.
2484
+ For local development, run via 'agentcore dev' which loads agentcore/.env.
2485
+ """
2486
+ if os.getenv("LOCAL_DEV") == "1":
2487
+ api_key = os.getenv(IDENTITY_ENV_VAR)
2488
+ if not api_key:
2489
+ raise RuntimeError(
2490
+ f"{IDENTITY_ENV_VAR} not found. Add {IDENTITY_ENV_VAR}=your-key to .env.local"
2491
+ )
2492
+ return api_key
2493
+ return _agentcore_identity_api_key_provider()
2494
+
2495
+
2496
+ def load_model() -> AnthropicModel:
2497
+ """Get authenticated Anthropic model client."""
2498
+ return AnthropicModel(
2499
+ client_args={"api_key": _get_api_key()},
2500
+ model_id="claude-sonnet-4-5-20250929",
2501
+ max_tokens=5000,
2502
+ )
2503
+ {{/if}}
2504
+ {{#if (eq modelProvider "OpenAI")}}
2505
+ import os
2506
+
2507
+ from strands.models.openai import OpenAIModel
2508
+ from bedrock_agentcore.identity.auth import requires_api_key
2509
+
2510
+ IDENTITY_PROVIDER_NAME = "{{identityProviders.[0].name}}"
2511
+ IDENTITY_ENV_VAR = "{{identityProviders.[0].envVarName}}"
2512
+
2513
+
2514
+ @requires_api_key(provider_name=IDENTITY_PROVIDER_NAME)
2515
+ def _agentcore_identity_api_key_provider(api_key: str) -> str:
2516
+ """Fetch API key from AgentCore Identity."""
2517
+ return api_key
2518
+
2519
+
2520
+ def _get_api_key() -> str:
2521
+ """
2522
+ Uses AgentCore Identity for API key management in deployed environments.
2523
+ For local development, run via 'agentcore dev' which loads agentcore/.env.
2524
+ """
2525
+ if os.getenv("LOCAL_DEV") == "1":
2526
+ api_key = os.getenv(IDENTITY_ENV_VAR)
2527
+ if not api_key:
2528
+ raise RuntimeError(
2529
+ f"{IDENTITY_ENV_VAR} not found. Add {IDENTITY_ENV_VAR}=your-key to .env.local"
2530
+ )
2531
+ return api_key
2532
+ return _agentcore_identity_api_key_provider()
2533
+
2534
+
2535
+ def load_model() -> OpenAIModel:
2536
+ """Get authenticated OpenAI model client."""
2537
+ return OpenAIModel(
2538
+ client_args={"api_key": _get_api_key()},
2539
+ model_id="gpt-4o",
2540
+ )
2541
+ {{/if}}
2542
+ {{#if (eq modelProvider "Gemini")}}
2543
+ import os
2544
+
2545
+ from strands.models.gemini import GeminiModel
2546
+ from bedrock_agentcore.identity.auth import requires_api_key
2547
+
2548
+ IDENTITY_PROVIDER_NAME = "{{identityProviders.[0].name}}"
2549
+ IDENTITY_ENV_VAR = "{{identityProviders.[0].envVarName}}"
2550
+
2551
+
2552
+ @requires_api_key(provider_name=IDENTITY_PROVIDER_NAME)
2553
+ def _agentcore_identity_api_key_provider(api_key: str) -> str:
2554
+ """Fetch API key from AgentCore Identity."""
2555
+ return api_key
2556
+
2557
+
2558
+ def _get_api_key() -> str:
2559
+ """
2560
+ Uses AgentCore Identity for API key management in deployed environments.
2561
+ For local development, run via 'agentcore dev' which loads agentcore/.env.
2562
+ """
2563
+ if os.getenv("LOCAL_DEV") == "1":
2564
+ api_key = os.getenv(IDENTITY_ENV_VAR)
2565
+ if not api_key:
2566
+ raise RuntimeError(
2567
+ f"{IDENTITY_ENV_VAR} not found. Add {IDENTITY_ENV_VAR}=your-key to .env.local"
2568
+ )
2569
+ return api_key
2570
+ return _agentcore_identity_api_key_provider()
2571
+
2572
+
2573
+ def load_model() -> GeminiModel:
2574
+ """Get authenticated Gemini model client."""
2575
+ return GeminiModel(
2576
+ client_args={"api_key": _get_api_key()},
2577
+ model_id="gemini-2.0-flash",
2578
+ )
2579
+ {{/if}}
2580
+ "
2581
+ `;
2582
+
2583
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/strands/base/pyproject.toml should match snapshot 1`] = `
2584
+ "[build-system]
2585
+ requires = ["hatchling"]
2586
+ build-backend = "hatchling.build"
2587
+
2588
+ [project]
2589
+ name = "{{ name }}"
2590
+ version = "0.1.0"
2591
+ description = "AgentCore Runtime Application using Strands SDK"
2592
+ readme = "README.md"
2593
+ requires-python = ">=3.10"
2594
+ dependencies = [
2595
+ "anthropic >= 0.30.0",
2596
+ "aws-opentelemetry-distro",
2597
+ "bedrock-agentcore >= 1.0.3",
2598
+ "botocore[crt] >= 1.35.0",
2599
+ "google-genai >= 1.0.0",
2600
+ "openai >= 1.0.0",
2601
+ "python-dotenv >= 1.0.1",
2602
+ "strands-agents >= 1.13.0",
2603
+ ]
2604
+
2605
+ [tool.hatch.build.targets.wheel]
2606
+ packages = ["."]
2607
+ "
2608
+ `;
2609
+
2610
+ exports[`Assets Directory Snapshots > Python framework assets > python/python/strands/capabilities/memory/session.py should match snapshot 1`] = `
2611
+ "import os
2612
+ from typing import Optional
2613
+
2614
+ from bedrock_agentcore.memory.integrations.strands.config import AgentCoreMemoryConfig{{#if memoryProviders.[0].strategies.length}}, RetrievalConfig{{/if}}
2615
+ from bedrock_agentcore.memory.integrations.strands.session_manager import AgentCoreMemorySessionManager
2616
+
2617
+ MEMORY_ID = os.getenv("{{memoryProviders.[0].envVarName}}")
2618
+ REGION = os.getenv("AWS_REGION")
2619
+
2620
+ def get_memory_session_manager(session_id: str, actor_id: str) -> Optional[AgentCoreMemorySessionManager]:
2621
+ if not MEMORY_ID:
2622
+ return None
2623
+
2624
+ {{#if memoryProviders.[0].strategies.length}}
2625
+ retrieval_config = {
2626
+ {{#if (includes memoryProviders.[0].strategies "SEMANTIC")}}
2627
+ f"/users/{actor_id}/facts": RetrievalConfig(top_k=3, relevance_score=0.5),
2628
+ {{/if}}
2629
+ {{#if (includes memoryProviders.[0].strategies "USER_PREFERENCE")}}
2630
+ f"/users/{actor_id}/preferences": RetrievalConfig(top_k=3, relevance_score=0.5),
2631
+ {{/if}}
2632
+ {{#if (includes memoryProviders.[0].strategies "SUMMARIZATION")}}
2633
+ f"/summaries/{actor_id}/{session_id}": RetrievalConfig(top_k=3, relevance_score=0.5),
2634
+ {{/if}}
2635
+ }
2636
+ {{/if}}
2637
+
2638
+ return AgentCoreMemorySessionManager(
2639
+ AgentCoreMemoryConfig(
2640
+ memory_id=MEMORY_ID,
2641
+ session_id=session_id,
2642
+ actor_id=actor_id,
2643
+ {{#if memoryProviders.[0].strategies.length}}
2644
+ retrieval_config=retrieval_config,
2645
+ {{/if}}
2646
+ ),
2647
+ REGION
2648
+ )
2649
+
2650
+ "
2651
+ `;
2652
+
2653
+ exports[`Assets Directory Snapshots > Root-level assets > AGENTS.md should match snapshot 1`] = `
2654
+ "## AgentCore Templates
2655
+
2656
+ This directory stores:
2657
+
2658
+ - Template assets for agents written in different Languages, SDKs and having different configurations
2659
+
2660
+ The rendering logic is rooted in the \`AgentEnvSpec\` and must ALWAYS respect the configuration in the Spec
2661
+
2662
+ ## Guidance for template changes
2663
+
2664
+ - Always make sure the templates are as close to working code as possible
2665
+ - AVOID as much as possible using any conditionals within the templates
2666
+
2667
+ # How to use the assets in this directory
2668
+
2669
+ - These assets are rendered by the CLI's template renderer in \`packages/agentcore-cli/src/templates\`.
2670
+ "
2671
+ `;
2672
+
2673
+ exports[`Assets Directory Snapshots > Root-level assets > README.md should match snapshot 1`] = `
2674
+ "# AgentCore Project
2675
+
2676
+ This project was created with the [AgentCore CLI](https://github.com/aws/agentcore-cli).
2677
+
2678
+ ## Project Structure
2679
+
2680
+ \`\`\`
2681
+ .
2682
+ my-project/
2683
+ ├── agentcore/
2684
+ │ ├── .env.local # API keys (gitignored)
2685
+ │ ├── agentcore.json # Resource specifications
2686
+ │ ├── aws-targets.json # Deployment targets
2687
+ │ └── cdk/ # CDK infrastructure
2688
+ ├── app/ # Application code
2689
+ \`\`\`
2690
+
2691
+ ## Getting Started
2692
+
2693
+ ### Prerequisites
2694
+
2695
+ - **Node.js** 20.x or later
2696
+ - **uv** for Python agents ([install](https://docs.astral.sh/uv/getting-started/installation/))
2697
+
2698
+ ### Development
2699
+
2700
+ Run your agent locally:
2701
+
2702
+ \`\`\`bash
2703
+ agentcore dev
2704
+ \`\`\`
2705
+
2706
+ ### Deployment
2707
+
2708
+ Deploy to AWS:
2709
+
2710
+ \`\`\`bash
2711
+ agentcore deploy
2712
+ \`\`\`
2713
+
2714
+ Or use CDK directly:
2715
+
2716
+ \`\`\`bash
2717
+ cd agentcore/cdk
2718
+ npx cdk deploy
2719
+ \`\`\`
2720
+
2721
+ ## Configuration
2722
+
2723
+ Edit the JSON files in \`agentcore/\` to configure your agents, memory, and credentials. See \`agentcore/.llm-context/\` for
2724
+ type definitions and validation constraints.
2725
+
2726
+ The project uses a **flat resource model** where agents, memories, and credentials are top-level arrays in
2727
+ \`agentcore.json\`.
2728
+
2729
+ ## Commands
2730
+
2731
+ | Command | Description |
2732
+ | -------------------- | ----------------------------------------------- |
2733
+ | \`agentcore create\` | Create a new AgentCore project |
2734
+ | \`agentcore add\` | Add resources (agent, memory, identity, target) |
2735
+ | \`agentcore remove\` | Remove resources |
2736
+ | \`agentcore dev\` | Run agent locally |
2737
+ | \`agentcore deploy\` | Deploy to AWS |
2738
+ | \`agentcore status\` | Show deployment status |
2739
+ | \`agentcore invoke\` | Invoke agent (local or deployed) |
2740
+ | \`agentcore package\` | Package agent artifacts |
2741
+ | \`agentcore validate\` | Validate configuration |
2742
+ | \`agentcore update\` | Check for CLI updates |
2743
+
2744
+ ### Agent Types
2745
+
2746
+ - **Template agents**: Created from framework templates (Strands, LangChain_LangGraph, GoogleADK, OpenAIAgents)
2747
+ - **BYO agents**: Bring your own code with \`agentcore add agent --type byo\`
2748
+
2749
+ ## Documentation
2750
+
2751
+ - [AgentCore CLI Documentation](https://github.com/aws/agentcore-cli)
2752
+ - [Amazon Bedrock AgentCore](https://aws.amazon.com/bedrock/agentcore/)
2753
+ "
2754
+ `;
2755
+
2756
+ exports[`Assets Directory Snapshots > Root-level assets > agents/AGENTS.md should match snapshot 1`] = `
2757
+ "# AgentCore Project
2758
+
2759
+ This project contains configuration and infrastructure for an Amazon Bedrock AgentCore application.
2760
+
2761
+ The \`agentcore/\` directory serves as a declarative model of an AgentCore project along with a concrete implementation
2762
+ through the \`agentcore/cdk/\` project which is modeled to take the configs as input. The project uses a **flat resource
2763
+ model** where agents, memories, and credentials are top-level arrays.
2764
+
2765
+ ## Mental Model
2766
+
2767
+ The project uses a **flat resource model**. Agents, memories, and credentials are independent top-level arrays in
2768
+ \`agentcore.json\`. There is no binding or attachment between resources in the schema — each resource is provisioned
2769
+ independently. To use a memory or credential from an agent, the application code discovers the resource at runtime
2770
+ (e.g., via environment variables or SDK calls).
2771
+
2772
+ ## Critical Invariants
2773
+
2774
+ 1. **Schema-First Authority:** The \`.json\` files are the absolute source of truth. Do not attempt to modify agent
2775
+ behavior by editing the generated CDK code in \`cdk/\`.
2776
+ 2. **Resource Identity:** The \`name\` field in the schema determines the CloudFormation Logical ID.
2777
+ - **Renaming** an agent or target will **destroy and recreate** that resource.
2778
+ - **Modifying** other fields (descriptions, config) will update the resource **in-place**.
2779
+ 3. **1:1 Validation:** The schema maps directly to valid CloudFormation. If your JSON conforms to the types in
2780
+ \`.llm-context/\`, it will deploy successfully.
2781
+ 4. **Resource Removal:** To remove all resources, use \`agentcore remove all\`. To tear down deployed infrastructure, run
2782
+ \`agentcore deploy\` after removal — it will detect the empty state and offer a teardown flow.
2783
+
2784
+ ## Directory Structure
2785
+
2786
+ \`\`\`
2787
+ myNewProject/
2788
+ ├── AGENTS.md # This file - AI coding assistant context
2789
+ ├── agentcore/ # AgentCore configuration directory
2790
+ │ ├── agentcore.json # Main project config (AgentCoreProjectSpec)
2791
+ │ ├── aws-targets.json # Deployment targets
2792
+ │ ├── .llm-context/ # TypeScript type definitions for AI coding assistants
2793
+ │ │ ├── README.md # Guide to using the schema files
2794
+ │ │ ├── agentcore.ts # AgentCoreProjectSpec types
2795
+ │ │ └── aws-targets.ts # AWS deployment target types
2796
+ │ └── cdk/ # AWS CDK project for deployment
2797
+ └── app/ # Application code (if agents were created)
2798
+ \`\`\`
2799
+
2800
+ ## Schema Reference
2801
+
2802
+ The \`agentcore/.llm-context/\` directory contains TypeScript type definitions optimized for AI coding assistants. Each
2803
+ file maps to a JSON config file and includes validation constraints as comments.
2804
+
2805
+ | JSON Config | Schema File | Root Type |
2806
+ | ---------------------------- | --------------------------------------- | ----------------------- |
2807
+ | \`agentcore/agentcore.json\` | \`agentcore/.llm-context/agentcore.ts\` | \`AgentCoreProjectSpec\` |
2808
+ | \`agentcore/aws-targets.json\` | \`agentcore/.llm-context/aws-targets.ts\` | \`AWSDeploymentTarget[]\` |
2809
+
2810
+ ### Key Types
2811
+
2812
+ - **AgentCoreProjectSpec**: Root project configuration with \`agents\`, \`memories\`, \`credentials\` arrays
2813
+ - **AgentEnvSpec**: Agent configuration (runtime, entrypoint, code location)
2814
+ - **Memory**: Memory resource with strategies and expiry
2815
+ - **Credential**: API key credential provider
2816
+
2817
+ ### Common Enum Values
2818
+
2819
+ - **BuildType**: \`'CodeZip'\`
2820
+ - **NetworkMode**: \`'PUBLIC'\`
2821
+ - **RuntimeVersion**: \`'PYTHON_3_10'\` | \`'PYTHON_3_11'\` | \`'PYTHON_3_12'\` | \`'PYTHON_3_13'\`
2822
+ - **MemoryStrategyType**: \`'SEMANTIC'\` | \`'SUMMARIZATION'\` | \`'USER_PREFERENCE'\`
2823
+
2824
+ ### Supported Frameworks (for template agents)
2825
+
2826
+ - **Strands** - Works with Bedrock, Anthropic, OpenAI, Gemini
2827
+ - **LangChain_LangGraph** - Works with Bedrock, Anthropic, OpenAI, Gemini
2828
+ - **GoogleADK** - Gemini only
2829
+ - **OpenAIAgents** - OpenAI only
2830
+
2831
+ ### Specific Context
2832
+
2833
+ Directory pathing to local projects is required for runtimes. Only Python offers a zip based direct code deploy option.
2834
+
2835
+ ## Deployment
2836
+
2837
+ The \`agentcore/cdk/\` subdirectory contains an AWS CDK node project.
2838
+
2839
+ Deployments of this project are primarily intended to be orchestrated through the \`agentcore deploy\` command in the CLI.
2840
+
2841
+ Alternatively, the project can be deployed directly as a traditional CDK project:
2842
+
2843
+ \`\`\`bash
2844
+ cd agentcore/cdk
2845
+ npm install
2846
+ npx cdk synth # Preview CloudFormation template
2847
+ npx cdk deploy # Deploy to AWS
2848
+ \`\`\`
2849
+
2850
+ ## Editing Schemas
2851
+
2852
+ When modifying JSON config files:
2853
+
2854
+ 1. Read the corresponding \`agentcore/.llm-context/*.ts\` file for type definitions
2855
+ 2. Check validation constraint comments (\`@regex\`, \`@min\`, \`@max\`)
2856
+ 3. Use exact enum values as string literals
2857
+ 4. Use CloudFormation-safe names (alphanumeric, start with letter)
2858
+ 5. Run \`agentcore validate\` command to verify changes.
2859
+ "
2860
+ `;
2861
+
2862
+ exports[`Assets Directory Snapshots > TypeScript assets > typescript/typescript/.gitkeep should match snapshot 1`] = `""`;