@aws/agentcore 1.0.0-preview.1 → 1.0.0-preview.11

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 (191) hide show
  1. package/README.md +56 -23
  2. package/dist/agent-inspector/index.css +1 -1
  3. package/dist/agent-inspector/index.js +87 -83
  4. package/dist/assets/__tests__/__snapshots__/assets.snapshot.test.ts.snap +809 -53
  5. package/dist/assets/__tests__/__snapshots__/dockerfile-render.test.ts.snap +6 -2
  6. package/dist/assets/__tests__/assets.snapshot.test.ts +10 -24
  7. package/dist/assets/cdk/bin/cdk.ts +6 -4
  8. package/dist/assets/cdk/cdk.json +1 -1
  9. package/dist/assets/cdk/lib/cdk-stack.ts +20 -14
  10. package/dist/assets/cdk/test/cdk.test.ts +1 -0
  11. package/dist/assets/container/python/Dockerfile +3 -1
  12. package/dist/assets/container/typescript/Dockerfile +25 -0
  13. package/dist/assets/container/typescript/dockerignore.template +24 -0
  14. package/dist/assets/datasets/predefined-v1.jsonl +3 -0
  15. package/dist/assets/datasets/simulated-v1.jsonl +3 -0
  16. package/dist/assets/evaluators/python-lambda/execution-role-policy.json +1 -1
  17. package/dist/assets/python/a2a/googleadk/base/pyproject.toml +3 -3
  18. package/dist/assets/python/a2a/langchain_langgraph/base/pyproject.toml +2 -1
  19. package/dist/assets/python/a2a/strands/base/pyproject.toml +2 -2
  20. package/dist/assets/python/a2a/strands/capabilities/memory/session.py +7 -2
  21. package/dist/assets/python/agui/googleadk/base/pyproject.toml +2 -2
  22. package/dist/assets/python/agui/langchain_langgraph/base/pyproject.toml +1 -0
  23. package/dist/assets/python/agui/strands/base/pyproject.toml +1 -1
  24. package/dist/assets/python/agui/strands/capabilities/memory/session.py +7 -2
  25. package/dist/assets/python/http/googleadk/base/pyproject.toml +2 -1
  26. package/dist/assets/python/http/langchain_langgraph/base/main.py +52 -8
  27. package/dist/assets/python/http/langchain_langgraph/base/pyproject.toml +1 -0
  28. package/dist/assets/python/http/strands/base/main.py +71 -8
  29. package/dist/assets/python/http/strands/base/pyproject.toml +1 -1
  30. package/dist/assets/python/http/strands/capabilities/memory/session.py +7 -2
  31. package/dist/assets/typescript/http/strands/base/README.md +37 -0
  32. package/dist/assets/typescript/http/strands/base/gitignore.template +22 -0
  33. package/dist/assets/typescript/http/strands/base/main.ts +66 -0
  34. package/dist/assets/typescript/http/strands/base/mcp_client/client.ts +11 -0
  35. package/dist/assets/typescript/http/strands/base/model/load.ts +102 -0
  36. package/dist/assets/typescript/http/strands/base/package.json +37 -0
  37. package/dist/assets/typescript/http/strands/base/tsconfig.json +19 -0
  38. package/dist/assets/typescript/http/vercelai/base/README.md +37 -0
  39. package/dist/assets/typescript/http/vercelai/base/gitignore.template +22 -0
  40. package/dist/assets/typescript/http/vercelai/base/main.ts +24 -0
  41. package/dist/assets/typescript/http/vercelai/base/model/load.ts +121 -0
  42. package/dist/assets/typescript/http/vercelai/base/package.json +35 -0
  43. package/dist/assets/typescript/http/vercelai/base/tsconfig.json +19 -0
  44. package/dist/cli/index.mjs +1311 -726
  45. package/dist/lib/errors/index.d.ts +1 -1
  46. package/dist/lib/errors/index.d.ts.map +1 -1
  47. package/dist/lib/errors/index.js +1 -1
  48. package/dist/lib/errors/index.js.map +1 -1
  49. package/dist/lib/errors/types.d.ts +189 -0
  50. package/dist/lib/errors/types.d.ts.map +1 -0
  51. package/dist/lib/errors/types.js +293 -0
  52. package/dist/lib/errors/types.js.map +1 -0
  53. package/dist/lib/errors/zod.d.ts +8 -0
  54. package/dist/lib/errors/zod.d.ts.map +1 -0
  55. package/dist/lib/errors/{config.js → zod.js} +7 -80
  56. package/dist/lib/errors/zod.js.map +1 -0
  57. package/dist/lib/index.d.ts +3 -0
  58. package/dist/lib/index.d.ts.map +1 -1
  59. package/dist/lib/index.js +4 -1
  60. package/dist/lib/index.js.map +1 -1
  61. package/dist/lib/packaging/build-args.js +2 -2
  62. package/dist/lib/packaging/build-args.js.map +1 -1
  63. package/dist/lib/packaging/container.js +5 -5
  64. package/dist/lib/packaging/container.js.map +1 -1
  65. package/dist/lib/packaging/helpers.d.ts +16 -0
  66. package/dist/lib/packaging/helpers.d.ts.map +1 -1
  67. package/dist/lib/packaging/helpers.js +77 -19
  68. package/dist/lib/packaging/helpers.js.map +1 -1
  69. package/dist/lib/packaging/index.d.ts +0 -1
  70. package/dist/lib/packaging/index.d.ts.map +1 -1
  71. package/dist/lib/packaging/index.js +4 -19
  72. package/dist/lib/packaging/index.js.map +1 -1
  73. package/dist/lib/packaging/node.d.ts +2 -2
  74. package/dist/lib/packaging/node.d.ts.map +1 -1
  75. package/dist/lib/packaging/node.js +83 -38
  76. package/dist/lib/packaging/node.js.map +1 -1
  77. package/dist/lib/packaging/python.js +12 -12
  78. package/dist/lib/packaging/python.js.map +1 -1
  79. package/dist/lib/result.d.ts +44 -0
  80. package/dist/lib/result.d.ts.map +1 -0
  81. package/dist/lib/result.js +28 -0
  82. package/dist/lib/result.js.map +1 -0
  83. package/dist/lib/schemas/io/config-io.d.ts.map +1 -1
  84. package/dist/lib/schemas/io/config-io.js +11 -3
  85. package/dist/lib/schemas/io/config-io.js.map +1 -1
  86. package/dist/lib/schemas/io/global-config.d.ts +40 -0
  87. package/dist/lib/schemas/io/global-config.d.ts.map +1 -0
  88. package/dist/lib/schemas/io/global-config.js +118 -0
  89. package/dist/lib/schemas/io/global-config.js.map +1 -0
  90. package/dist/lib/schemas/io/index.d.ts +1 -2
  91. package/dist/lib/schemas/io/index.d.ts.map +1 -1
  92. package/dist/lib/schemas/io/index.js +1 -4
  93. package/dist/lib/schemas/io/index.js.map +1 -1
  94. package/dist/lib/schemas/io/path-resolver.d.ts +0 -6
  95. package/dist/lib/schemas/io/path-resolver.d.ts.map +1 -1
  96. package/dist/lib/schemas/io/path-resolver.js +3 -13
  97. package/dist/lib/schemas/io/path-resolver.js.map +1 -1
  98. package/dist/lib/time-constants.d.ts +5 -0
  99. package/dist/lib/time-constants.d.ts.map +1 -0
  100. package/dist/lib/time-constants.js +8 -0
  101. package/dist/lib/time-constants.js.map +1 -0
  102. package/dist/lib/utils/index.d.ts +2 -1
  103. package/dist/lib/utils/index.d.ts.map +1 -1
  104. package/dist/lib/utils/index.js +5 -1
  105. package/dist/lib/utils/index.js.map +1 -1
  106. package/dist/lib/utils/polling.d.ts +31 -0
  107. package/dist/lib/utils/polling.d.ts.map +1 -0
  108. package/dist/lib/utils/polling.js +61 -0
  109. package/dist/lib/utils/polling.js.map +1 -0
  110. package/dist/lib/utils/zod.d.ts +16 -0
  111. package/dist/lib/utils/zod.d.ts.map +1 -1
  112. package/dist/lib/utils/zod.js +45 -0
  113. package/dist/lib/utils/zod.js.map +1 -1
  114. package/dist/schema/constants.d.ts +7 -0
  115. package/dist/schema/constants.d.ts.map +1 -1
  116. package/dist/schema/constants.js +18 -3
  117. package/dist/schema/constants.js.map +1 -1
  118. package/dist/schema/schemas/agent-env.d.ts +25 -1
  119. package/dist/schema/schemas/agent-env.d.ts.map +1 -1
  120. package/dist/schema/schemas/agent-env.js +51 -5
  121. package/dist/schema/schemas/agent-env.js.map +1 -1
  122. package/dist/schema/schemas/agentcore-project.d.ts +161 -5
  123. package/dist/schema/schemas/agentcore-project.d.ts.map +1 -1
  124. package/dist/schema/schemas/agentcore-project.js +159 -13
  125. package/dist/schema/schemas/agentcore-project.js.map +1 -1
  126. package/dist/schema/schemas/aws-targets.d.ts +3 -0
  127. package/dist/schema/schemas/aws-targets.d.ts.map +1 -1
  128. package/dist/schema/schemas/aws-targets.js +1 -0
  129. package/dist/schema/schemas/aws-targets.js.map +1 -1
  130. package/dist/schema/schemas/deployed-state.d.ts +165 -0
  131. package/dist/schema/schemas/deployed-state.d.ts.map +1 -1
  132. package/dist/schema/schemas/deployed-state.js +59 -1
  133. package/dist/schema/schemas/deployed-state.js.map +1 -1
  134. package/dist/schema/schemas/mcp.d.ts +2 -0
  135. package/dist/schema/schemas/mcp.d.ts.map +1 -1
  136. package/dist/schema/schemas/mcp.js +10 -2
  137. package/dist/schema/schemas/mcp.js.map +1 -1
  138. package/dist/schema/schemas/primitives/ab-test.d.ts +141 -0
  139. package/dist/schema/schemas/primitives/ab-test.d.ts.map +1 -0
  140. package/dist/schema/schemas/primitives/ab-test.js +97 -0
  141. package/dist/schema/schemas/primitives/ab-test.js.map +1 -0
  142. package/dist/schema/schemas/primitives/config-bundle.d.ts +31 -0
  143. package/dist/schema/schemas/primitives/config-bundle.d.ts.map +1 -0
  144. package/dist/schema/schemas/primitives/config-bundle.js +38 -0
  145. package/dist/schema/schemas/primitives/config-bundle.js.map +1 -0
  146. package/dist/schema/schemas/primitives/dataset.d.ts +48 -0
  147. package/dist/schema/schemas/primitives/dataset.d.ts.map +1 -0
  148. package/dist/schema/schemas/primitives/dataset.js +58 -0
  149. package/dist/schema/schemas/primitives/dataset.js.map +1 -0
  150. package/dist/schema/schemas/primitives/evaluator.d.ts +8 -0
  151. package/dist/schema/schemas/primitives/evaluator.d.ts.map +1 -1
  152. package/dist/schema/schemas/primitives/evaluator.js +17 -1
  153. package/dist/schema/schemas/primitives/evaluator.js.map +1 -1
  154. package/dist/schema/schemas/primitives/harness.d.ts +84 -8
  155. package/dist/schema/schemas/primitives/harness.d.ts.map +1 -1
  156. package/dist/schema/schemas/primitives/harness.js +29 -5
  157. package/dist/schema/schemas/primitives/harness.js.map +1 -1
  158. package/dist/schema/schemas/primitives/http-gateway.d.ts +21 -0
  159. package/dist/schema/schemas/primitives/http-gateway.d.ts.map +1 -0
  160. package/dist/schema/schemas/primitives/http-gateway.js +34 -0
  161. package/dist/schema/schemas/primitives/http-gateway.js.map +1 -0
  162. package/dist/schema/schemas/primitives/index.d.ts +9 -3
  163. package/dist/schema/schemas/primitives/index.d.ts.map +1 -1
  164. package/dist/schema/schemas/primitives/index.js +24 -1
  165. package/dist/schema/schemas/primitives/index.js.map +1 -1
  166. package/dist/schema/schemas/primitives/memory.d.ts +22 -4
  167. package/dist/schema/schemas/primitives/memory.d.ts.map +1 -1
  168. package/dist/schema/schemas/primitives/memory.js +57 -16
  169. package/dist/schema/schemas/primitives/memory.js.map +1 -1
  170. package/dist/schema/schemas/primitives/online-eval-config.d.ts +1 -0
  171. package/dist/schema/schemas/primitives/online-eval-config.d.ts.map +1 -1
  172. package/dist/schema/schemas/primitives/online-eval-config.js +2 -0
  173. package/dist/schema/schemas/primitives/online-eval-config.js.map +1 -1
  174. package/npm-shrinkwrap.json +16604 -0
  175. package/package.json +27 -15
  176. package/scripts/bump-version.ts +4 -4
  177. package/scripts/bundle.mjs +92 -66
  178. package/scripts/run-e2e-dev.sh +56 -0
  179. package/scripts/run-e2e-local.sh +112 -0
  180. package/dist/agent-inspector/index.js.map +0 -1
  181. package/dist/lib/errors/config.d.ts +0 -49
  182. package/dist/lib/errors/config.d.ts.map +0 -1
  183. package/dist/lib/errors/config.js.map +0 -1
  184. package/dist/lib/packaging/errors.d.ts +0 -16
  185. package/dist/lib/packaging/errors.d.ts.map +0 -1
  186. package/dist/lib/packaging/errors.js +0 -36
  187. package/dist/lib/packaging/errors.js.map +0 -1
  188. package/dist/lib/schemas/io/cli-config.d.ts +0 -12
  189. package/dist/lib/schemas/io/cli-config.d.ts.map +0 -1
  190. package/dist/lib/schemas/io/cli-config.js +0 -35
  191. package/dist/lib/schemas/io/cli-config.js.map +0 -1
@@ -100,9 +100,6 @@ async function main() {
100
100
  }
101
101
 
102
102
  // Read harness configs for role creation.
103
- // Harness fields may not yet be on the AgentCoreProjectSpec type from @aws/agentcore-cdk,
104
- // so we read them dynamically via specAny (same pattern as gateways above).
105
- // Harness paths in agentcore.json are relative to the project root (parent of agentcore/).
106
103
  const projectRoot = path.resolve(configRoot, '..');
107
104
  const harnessConfigs: {
108
105
  name: string;
@@ -110,11 +107,14 @@ async function main() {
110
107
  memoryName?: string;
111
108
  containerUri?: string;
112
109
  hasDockerfile?: boolean;
110
+ dockerfile?: string;
111
+ codeLocation?: string;
113
112
  tools?: { type: string; name: string }[];
114
113
  apiKeyArn?: string;
115
114
  }[] = [];
116
115
  for (const entry of specAny.harnesses ?? []) {
117
- const harnessPath = path.resolve(projectRoot, entry.path, 'harness.json');
116
+ const harnessDir = path.resolve(projectRoot, entry.path);
117
+ const harnessPath = path.resolve(harnessDir, 'harness.json');
118
118
  try {
119
119
  const harnessSpec = JSON.parse(fs.readFileSync(harnessPath, 'utf-8'));
120
120
  harnessConfigs.push({
@@ -123,6 +123,8 @@ async function main() {
123
123
  memoryName: harnessSpec.memory?.name,
124
124
  containerUri: harnessSpec.containerUri,
125
125
  hasDockerfile: !!harnessSpec.dockerfile,
126
+ dockerfile: harnessSpec.dockerfile,
127
+ codeLocation: harnessSpec.dockerfile ? harnessDir : undefined,
126
128
  tools: harnessSpec.tools,
127
129
  apiKeyArn: harnessSpec.model?.apiKeyArn,
128
130
  });
@@ -184,7 +186,7 @@ exports[`Assets Directory Snapshots > CDK assets > cdk/cdk/cdk.json should match
184
186
  "@aws-cdk/aws-ecs-patterns:secGroupsDisablesImplicitOpenListener": true,
185
187
  "@aws-cdk/aws-lambda:recognizeLayerVersion": true,
186
188
  "@aws-cdk/core:checkSecretUsage": true,
187
- "@aws-cdk/core:target-partitions": ["aws", "aws-cn"],
189
+ "@aws-cdk/core:target-partitions": ["aws", "aws-cn", "aws-us-gov"],
188
190
  "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
189
191
  "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
190
192
  "@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true,
@@ -300,6 +302,18 @@ exports[`Assets Directory Snapshots > CDK assets > cdk/cdk/lib/cdk-stack.ts shou
300
302
  import { CfnOutput, Stack, type StackProps } from 'aws-cdk-lib';
301
303
  import { Construct } from 'constructs';
302
304
 
305
+ export interface HarnessConfig {
306
+ name: string;
307
+ executionRoleArn?: string;
308
+ memoryName?: string;
309
+ containerUri?: string;
310
+ hasDockerfile?: boolean;
311
+ dockerfile?: string;
312
+ codeLocation?: string;
313
+ tools?: { type: string; name: string }[];
314
+ apiKeyArn?: string;
315
+ }
316
+
303
317
  export interface AgentCoreStackProps extends StackProps {
304
318
  /**
305
319
  * The AgentCore project specification containing agents, memories, and credentials.
@@ -314,17 +328,9 @@ export interface AgentCoreStackProps extends StackProps {
314
328
  */
315
329
  credentials?: Record<string, { credentialProviderArn: string; clientSecretArn?: string }>;
316
330
  /**
317
- * Harness role configurations. Each entry creates an IAM execution role for a harness.
331
+ * Harness role configurations.
318
332
  */
319
- harnesses?: {
320
- name: string;
321
- executionRoleArn?: string;
322
- memoryName?: string;
323
- containerUri?: string;
324
- hasDockerfile?: boolean;
325
- tools?: { type: string; name: string }[];
326
- apiKeyArn?: string;
327
- }[];
333
+ harnesses?: HarnessConfig[];
328
334
  }
329
335
 
330
336
  /**
@@ -343,10 +349,12 @@ export class AgentCoreStack extends Stack {
343
349
  const { spec, mcpSpec, credentials, harnesses } = props;
344
350
 
345
351
  // Create AgentCoreApplication with all agents and harness roles
346
- this.application = new AgentCoreApplication(this, 'Application', {
347
- spec,
348
- harnesses,
349
- });
352
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
353
+ const appProps: Record<string, unknown> = { spec };
354
+ if (harnesses?.length) {
355
+ appProps.harnesses = harnesses;
356
+ }
357
+ this.application = new AgentCoreApplication(this, 'Application', appProps as any);
350
358
 
351
359
  // Create AgentCoreMcp if there are gateways configured
352
360
  if (mcpSpec?.agentCoreGateways && mcpSpec.agentCoreGateways.length > 0) {
@@ -434,6 +442,7 @@ test('AgentCoreStack synthesizes with empty spec', () => {
434
442
  agentCoreGateways: [],
435
443
  mcpRuntimeTools: [],
436
444
  unassignedTargets: [],
445
+ datasets: [],
437
446
  },
438
447
  });
439
448
  const template = Template.fromStack(stack);
@@ -494,6 +503,10 @@ exports[`Assets Directory Snapshots > File listing > should match the expected f
494
503
  "cdk/tsconfig.json",
495
504
  "container/python/Dockerfile",
496
505
  "container/python/dockerignore.template",
506
+ "container/typescript/Dockerfile",
507
+ "container/typescript/dockerignore.template",
508
+ "datasets/predefined-v1.jsonl",
509
+ "datasets/simulated-v1.jsonl",
497
510
  "evaluators/python-lambda/execution-role-policy.json",
498
511
  "evaluators/python-lambda/lambda_function.py",
499
512
  "evaluators/python-lambda/pyproject.toml",
@@ -591,6 +604,19 @@ exports[`Assets Directory Snapshots > File listing > should match the expected f
591
604
  "python/mcp/standalone/base/main.py",
592
605
  "python/mcp/standalone/base/pyproject.toml",
593
606
  "typescript/.gitkeep",
607
+ "typescript/http/strands/base/README.md",
608
+ "typescript/http/strands/base/gitignore.template",
609
+ "typescript/http/strands/base/main.ts",
610
+ "typescript/http/strands/base/mcp_client/client.ts",
611
+ "typescript/http/strands/base/model/load.ts",
612
+ "typescript/http/strands/base/package.json",
613
+ "typescript/http/strands/base/tsconfig.json",
614
+ "typescript/http/vercelai/base/README.md",
615
+ "typescript/http/vercelai/base/gitignore.template",
616
+ "typescript/http/vercelai/base/main.ts",
617
+ "typescript/http/vercelai/base/model/load.ts",
618
+ "typescript/http/vercelai/base/package.json",
619
+ "typescript/http/vercelai/base/tsconfig.json",
594
620
  ]
595
621
  `;
596
622
 
@@ -1212,11 +1238,11 @@ description = "AgentCore A2A Agent using Google ADK"
1212
1238
  readme = "README.md"
1213
1239
  requires-python = ">=3.10"
1214
1240
  dependencies = [
1215
- "a2a-sdk >= 0.2.0",
1241
+ "a2a-sdk >= 0.2.0, < 1.0.0",
1216
1242
  "aws-opentelemetry-distro",
1217
1243
  "bedrock-agentcore[a2a] >= 1.0.3",
1218
- "google-adk >= 1.0.0",
1219
- "google-genai >= 1.0.0",
1244
+ "google-adk >= 1.0.0, < 2.0.0",
1245
+ "google-genai >= 1.0.0, < 2.0.0",
1220
1246
  ]
1221
1247
 
1222
1248
  [tool.hatch.build.targets.wheel]
@@ -1573,10 +1599,11 @@ description = "AgentCore A2A Agent using LangChain + LangGraph"
1573
1599
  readme = "README.md"
1574
1600
  requires-python = ">=3.10"
1575
1601
  dependencies = [
1576
- "a2a-sdk >= 0.2.0",
1602
+ "a2a-sdk >= 0.2.0, < 1.0.0",
1577
1603
  {{#if (eq modelProvider "Anthropic")}}"langchain-anthropic >= 0.3.0",
1578
1604
  {{/if}}{{#if (eq modelProvider "Bedrock")}}"langchain-aws >= 0.2.0",
1579
1605
  {{/if}}{{#if (eq modelProvider "Gemini")}}"langchain-google-genai >= 2.0.0",
1606
+ "google-genai >= 1.0.0, < 2.0.0",
1580
1607
  {{/if}}{{#if (eq modelProvider "OpenAI")}}"langchain-openai >= 0.2.0",
1581
1608
  {{/if}}"aws-opentelemetry-distro",
1582
1609
  "opentelemetry-instrumentation-langchain >= 0.59.0",
@@ -1917,9 +1944,9 @@ readme = "README.md"
1917
1944
  requires-python = ">=3.10"
1918
1945
  dependencies = [
1919
1946
  {{#if (eq modelProvider "Anthropic")}}"anthropic >= 0.30.0",
1920
- {{/if}}"a2a-sdk[all] >= 0.2.0",
1947
+ {{/if}}"a2a-sdk[all] >= 0.2.0, < 1.0.0",
1921
1948
  "aws-opentelemetry-distro",
1922
- "bedrock-agentcore[a2a] >= 1.0.3",
1949
+ "bedrock-agentcore[a2a] >= 1.9.1",
1923
1950
  "botocore[crt] >= 1.35.0",
1924
1951
  {{#if (eq modelProvider "Gemini")}}"google-genai >= 1.0.0",
1925
1952
  {{/if}}{{#if (eq modelProvider "OpenAI")}}"openai >= 1.0.0",
@@ -1938,6 +1965,7 @@ exports[`Assets Directory Snapshots > Python framework assets > python/python/a2
1938
1965
 
1939
1966
  exports[`Assets Directory Snapshots > Python framework assets > python/python/a2a/strands/capabilities/memory/session.py should match snapshot 1`] = `
1940
1967
  "import os
1968
+ import uuid
1941
1969
  from typing import Optional
1942
1970
 
1943
1971
  from bedrock_agentcore.memory.integrations.strands.config import AgentCoreMemoryConfig{{#if memoryProviders.[0].strategies.length}}, RetrievalConfig{{/if}}
@@ -1946,10 +1974,14 @@ from bedrock_agentcore.memory.integrations.strands.session_manager import AgentC
1946
1974
  MEMORY_ID = os.getenv("{{memoryProviders.[0].envVarName}}")
1947
1975
  REGION = os.getenv("AWS_REGION")
1948
1976
 
1949
- def get_memory_session_manager(session_id: str, actor_id: str) -> Optional[AgentCoreMemorySessionManager]:
1977
+ def get_memory_session_manager(session_id: Optional[str], actor_id: str) -> Optional[AgentCoreMemorySessionManager]:
1950
1978
  if not MEMORY_ID:
1951
1979
  return None
1952
1980
 
1981
+ # AgentCoreMemoryConfig rejects None; OAuth/CUSTOM_JWT callers can reach us
1982
+ # without a runtime session header, so synthesize one when absent.
1983
+ session_id = session_id or uuid.uuid4().hex
1984
+
1953
1985
  {{#if memoryProviders.[0].strategies.length}}
1954
1986
  retrieval_config = {
1955
1987
  {{#if (includes memoryProviders.[0].strategies "SEMANTIC")}}
@@ -1959,7 +1991,7 @@ def get_memory_session_manager(session_id: str, actor_id: str) -> Optional[Agent
1959
1991
  f"/users/{actor_id}/preferences": RetrievalConfig(top_k=3, relevance_score=0.5),
1960
1992
  {{/if}}
1961
1993
  {{#if (includes memoryProviders.[0].strategies "SUMMARIZATION")}}
1962
- f"/summaries/{actor_id}/{session_id}": RetrievalConfig(top_k=3, relevance_score=0.5),
1994
+ f"/summaries/{actor_id}": RetrievalConfig(top_k=3, relevance_score=0.5),
1963
1995
  {{/if}}
1964
1996
  }
1965
1997
  {{/if}}
@@ -2158,8 +2190,8 @@ dependencies = [
2158
2190
  "ag-ui-protocol >= 0.1.10",
2159
2191
  "bedrock-agentcore >= 1.0.3",
2160
2192
  "fastapi >= 0.115.12",
2161
- "google-adk >= 1.16.0",
2162
- "google-genai >= 1.0.0",
2193
+ "google-adk >= 1.16.0, < 2.0.0",
2194
+ "google-genai >= 1.0.0, < 2.0.0",
2163
2195
  "opentelemetry-distro",
2164
2196
  "opentelemetry-exporter-otlp",
2165
2197
  "uvicorn >= 0.34.3",
@@ -2468,6 +2500,7 @@ dependencies = [
2468
2500
  {{#if (eq modelProvider "Anthropic")}}"langchain-anthropic >= 0.3.0",
2469
2501
  {{/if}}{{#if (eq modelProvider "Bedrock")}}"langchain-aws >= 0.2.0",
2470
2502
  {{/if}}{{#if (eq modelProvider "Gemini")}}"langchain-google-genai >= 2.0.0",
2503
+ "google-genai >= 1.0.0, < 2.0.0",
2471
2504
  {{/if}}{{#if (eq modelProvider "OpenAI")}}"langchain-openai >= 0.2.0",
2472
2505
  {{/if}}"aws-opentelemetry-distro",
2473
2506
  "opentelemetry-instrumentation-langchain >= 0.59.0",
@@ -2751,7 +2784,7 @@ dependencies = [
2751
2784
  {{/if}}"ag-ui-strands >= 0.1.7",
2752
2785
  "ag-ui-protocol >= 0.1.10",
2753
2786
  "aws-opentelemetry-distro",
2754
- "bedrock-agentcore >= 1.0.3",
2787
+ "bedrock-agentcore >= 1.9.1",
2755
2788
  "botocore[crt] >= 1.35.0",
2756
2789
  "fastapi >= 0.115.12",
2757
2790
  {{#if (eq modelProvider "Gemini")}}"google-genai >= 1.0.0",
@@ -2773,6 +2806,7 @@ exports[`Assets Directory Snapshots > Python framework assets > python/python/ag
2773
2806
 
2774
2807
  exports[`Assets Directory Snapshots > Python framework assets > python/python/agui/strands/capabilities/memory/session.py should match snapshot 1`] = `
2775
2808
  "import os
2809
+ import uuid
2776
2810
  from typing import Optional
2777
2811
 
2778
2812
  from bedrock_agentcore.memory.integrations.strands.config import AgentCoreMemoryConfig{{#if memoryProviders.[0].strategies.length}}, RetrievalConfig{{/if}}
@@ -2781,10 +2815,14 @@ from bedrock_agentcore.memory.integrations.strands.session_manager import AgentC
2781
2815
  MEMORY_ID = os.getenv("{{memoryProviders.[0].envVarName}}")
2782
2816
  REGION = os.getenv("AWS_REGION")
2783
2817
 
2784
- def get_memory_session_manager(session_id: str, actor_id: str) -> Optional[AgentCoreMemorySessionManager]:
2818
+ def get_memory_session_manager(session_id: Optional[str], actor_id: str) -> Optional[AgentCoreMemorySessionManager]:
2785
2819
  if not MEMORY_ID:
2786
2820
  return None
2787
2821
 
2822
+ # AgentCoreMemoryConfig rejects None; OAuth/CUSTOM_JWT callers can reach us
2823
+ # without a runtime session header, so synthesize one when absent.
2824
+ session_id = session_id or uuid.uuid4().hex
2825
+
2788
2826
  {{#if memoryProviders.[0].strategies.length}}
2789
2827
  retrieval_config = {
2790
2828
  {{#if (includes memoryProviders.[0].strategies "SEMANTIC")}}
@@ -2794,7 +2832,7 @@ def get_memory_session_manager(session_id: str, actor_id: str) -> Optional[Agent
2794
2832
  f"/users/{actor_id}/preferences": RetrievalConfig(top_k=3, relevance_score=0.5),
2795
2833
  {{/if}}
2796
2834
  {{#if (includes memoryProviders.[0].strategies "SUMMARIZATION")}}
2797
- f"/summaries/{actor_id}/{session_id}": RetrievalConfig(top_k=3, relevance_score=0.5),
2835
+ f"/summaries/{actor_id}": RetrievalConfig(top_k=3, relevance_score=0.5),
2798
2836
  {{/if}}
2799
2837
  }
2800
2838
  {{/if}}
@@ -3637,7 +3675,8 @@ requires-python = ">=3.10"
3637
3675
  dependencies = [
3638
3676
  "opentelemetry-distro",
3639
3677
  "opentelemetry-exporter-otlp",
3640
- "google-adk >= 1.17.0",
3678
+ "google-adk >= 1.17.0, < 2.0.0",
3679
+ "google-genai >= 1.0.0, < 2.0.0",
3641
3680
  "bedrock-agentcore >= 1.0.3",
3642
3681
  "botocore[crt] >= 1.35.0",
3643
3682
  {{#if hasGateway}}{{#if (includes gatewayAuthTypes "AWS_IAM")}}"mcp-proxy-for-aws >= 1.1.0",
@@ -3739,9 +3778,15 @@ Thumbs.db
3739
3778
 
3740
3779
  exports[`Assets Directory Snapshots > Python framework assets > python/python/http/langchain_langgraph/base/main.py should match snapshot 1`] = `
3741
3780
  "import os
3742
- from langchain_core.messages import HumanMessage
3781
+ from typing import Any
3782
+
3783
+ from langchain_core.messages import HumanMessage{{#if hasConfigBundle}}, SystemMessage{{/if}}
3743
3784
  from langgraph.prebuilt import create_react_agent
3744
3785
  from langchain.tools import tool
3786
+ {{#if hasConfigBundle}}
3787
+ from langchain_core.callbacks import BaseCallbackHandler
3788
+ from bedrock_agentcore.runtime.context import BedrockAgentCoreContext
3789
+ {{/if}}
3745
3790
  from opentelemetry.instrumentation.langchain import LangchainInstrumentor
3746
3791
  from bedrock_agentcore.runtime import BedrockAgentCoreApp
3747
3792
  from model.load import load_model
@@ -3765,6 +3810,14 @@ def get_or_create_model():
3765
3810
  return _llm
3766
3811
 
3767
3812
 
3813
+ DEFAULT_SYSTEM_PROMPT = """
3814
+ You are a helpful assistant. Use tools when appropriate.
3815
+ {{#if sessionStorageMountPath}}
3816
+ You have persistent storage at {{sessionStorageMountPath}}. Use file tools to read and write files. Data persists across sessions.
3817
+ {{/if}}
3818
+ """
3819
+
3820
+
3768
3821
  # Define a simple function tool
3769
3822
  @tool
3770
3823
  def add_numbers(a: int, b: int) -> int:
@@ -3828,13 +3881,28 @@ def list_files(directory: str = "") -> str:
3828
3881
  tools.extend([file_read, file_write, list_files])
3829
3882
  {{/if}}
3830
3883
 
3831
- SYSTEM_PROMPT = """
3832
- You are a helpful assistant. Use tools when appropriate.
3833
- {{#if sessionStorageMountPath}}
3834
- You have persistent storage at {{sessionStorageMountPath}}. Use file tools to read and write files. Data persists across sessions.
3835
- {{/if}}
3836
- """
3884
+ {{#if hasConfigBundle}}
3885
+
3886
+ class ConfigBundleCallback(BaseCallbackHandler):
3887
+ """Injects config bundle values into LangGraph agent at runtime.
3837
3888
 
3889
+ BedrockAgentCoreContext.get_config_bundle() fetches the component configuration
3890
+ for the current runtime ARN from the config bundle service. The SDK caches the
3891
+ result and refreshes on bundle version changes.
3892
+ """
3893
+
3894
+ def on_chain_start(self, serialized: dict, inputs: dict, **kwargs: Any) -> None:
3895
+ config = BedrockAgentCoreContext.get_config_bundle()
3896
+ prompt = config.get("systemPrompt", DEFAULT_SYSTEM_PROMPT)
3897
+
3898
+ messages = inputs.get("messages", [])
3899
+ if messages and isinstance(messages[0], SystemMessage):
3900
+ messages[0] = SystemMessage(content=prompt)
3901
+ else:
3902
+ messages.insert(0, SystemMessage(content=prompt))
3903
+ inputs["messages"] = messages
3904
+
3905
+ {{/if}}
3838
3906
 
3839
3907
  @app.entrypoint
3840
3908
  async def invoke(payload, context):
@@ -3853,7 +3921,21 @@ async def invoke(payload, context):
3853
3921
  mcp_tools = await mcp_client.get_tools()
3854
3922
 
3855
3923
  # Define the agent using create_react_agent
3856
- graph = create_react_agent(get_or_create_model(), tools=mcp_tools + tools, prompt=SYSTEM_PROMPT)
3924
+ {{#if hasConfigBundle}}
3925
+ graph = create_react_agent(get_or_create_model(), tools=mcp_tools + tools, prompt=DEFAULT_SYSTEM_PROMPT)
3926
+ callback = ConfigBundleCallback()
3927
+
3928
+ # Process the user prompt
3929
+ prompt = payload.get("prompt", "What can you help me with?")
3930
+ log.info(f"Agent input: {prompt}")
3931
+
3932
+ # Run the agent with config bundle callback
3933
+ result = await graph.ainvoke(
3934
+ {"messages": [HumanMessage(content=prompt)]},
3935
+ config={"callbacks": [callback]},
3936
+ )
3937
+ {{else}}
3938
+ graph = create_react_agent(get_or_create_model(), tools=mcp_tools + tools, prompt=DEFAULT_SYSTEM_PROMPT)
3857
3939
 
3858
3940
  # Process the user prompt
3859
3941
  prompt = payload.get("prompt", "What can you help me with?")
@@ -3861,6 +3943,7 @@ async def invoke(payload, context):
3861
3943
 
3862
3944
  # Run the agent
3863
3945
  result = await graph.ainvoke({"messages": [HumanMessage(content=prompt)]})
3946
+ {{/if}}
3864
3947
 
3865
3948
  # Return result
3866
3949
  output = result["messages"][-1].content
@@ -4122,6 +4205,7 @@ dependencies = [
4122
4205
  {{/if}}
4123
4206
  {{#if (eq modelProvider "Gemini")}}
4124
4207
  "langchain-google-genai >= 3.0.3",
4208
+ "google-genai >= 1.0.0, < 2.0.0",
4125
4209
  {{/if}}
4126
4210
  {{#if hasGateway}}{{#if (includes gatewayAuthTypes "AWS_IAM")}}"mcp-proxy-for-aws >= 1.1.0",
4127
4211
  {{/if}}{{/if}}
@@ -4635,7 +4719,13 @@ Thumbs.db"
4635
4719
  `;
4636
4720
 
4637
4721
  exports[`Assets Directory Snapshots > Python framework assets > python/python/http/strands/base/main.py should match snapshot 1`] = `
4638
- "from strands import Agent, tool
4722
+ "from typing import Any
4723
+
4724
+ from strands import Agent, tool
4725
+ {{#if hasConfigBundle}}
4726
+ from strands.hooks import HookProvider, HookRegistry, BeforeInvocationEvent, BeforeToolCallEvent
4727
+ from bedrock_agentcore.runtime.context import BedrockAgentCoreContext
4728
+ {{/if}}
4639
4729
  from bedrock_agentcore.runtime import BedrockAgentCoreApp
4640
4730
  from model.load import load_model
4641
4731
  {{#if hasGateway}}
@@ -4660,11 +4750,26 @@ mcp_clients = get_all_gateway_mcp_clients()
4660
4750
  mcp_clients = [get_streamable_http_mcp_client()]
4661
4751
  {{/if}}
4662
4752
 
4753
+ DEFAULT_SYSTEM_PROMPT = """
4754
+ You are a helpful assistant. Use tools when appropriate.
4755
+ {{#if sessionStorageMountPath}}
4756
+ You have persistent storage at {{sessionStorageMountPath}}. Use file tools to read and write files. Data persists across sessions.
4757
+ {{/if}}
4758
+ """
4759
+
4760
+ {{#if hasConfigBundle}}
4761
+ DEFAULT_TOOL_DESC = "Return the sum of two numbers"
4762
+ {{/if}}
4763
+
4663
4764
  # Define a collection of tools used by the model
4664
4765
  tools = []
4665
4766
 
4666
4767
  # Define a simple function tool
4768
+ {{#if hasConfigBundle}}
4769
+ @tool(description=DEFAULT_TOOL_DESC)
4770
+ {{else}}
4667
4771
  @tool
4772
+ {{/if}}
4668
4773
  def add_numbers(a: int, b: int) -> int:
4669
4774
  """Return the sum of two numbers"""
4670
4775
  return a+b
@@ -4728,12 +4833,39 @@ for mcp_client in mcp_clients:
4728
4833
  if mcp_client:
4729
4834
  tools.append(mcp_client)
4730
4835
 
4731
- SYSTEM_PROMPT = """
4732
- You are a helpful assistant. Use tools when appropriate.
4733
- {{#if sessionStorageMountPath}}
4734
- You have persistent storage at {{sessionStorageMountPath}}. Use file tools to read and write files. Data persists across sessions.
4836
+ {{#if hasConfigBundle}}
4837
+
4838
+ class ConfigBundleHook(HookProvider):
4839
+ """Injects config bundle values (system prompt, tool descriptions) before each invocation.
4840
+
4841
+ BedrockAgentCoreContext.get_config_bundle() fetches the component configuration
4842
+ for the current runtime ARN from the config bundle service. The SDK caches the
4843
+ result and refreshes on bundle version changes.
4844
+ """
4845
+
4846
+ def register_hooks(self, registry: HookRegistry, **kwargs: Any) -> None:
4847
+ registry.add_callback(BeforeInvocationEvent, self._inject_system_prompt)
4848
+ registry.add_callback(BeforeToolCallEvent, self._override_tool_desc)
4849
+
4850
+ def _inject_system_prompt(self, event: BeforeInvocationEvent) -> None:
4851
+ config = BedrockAgentCoreContext.get_config_bundle()
4852
+ prompt = config.get("systemPrompt", DEFAULT_SYSTEM_PROMPT)
4853
+
4854
+ if prompt != event.agent.system_prompt:
4855
+ event.agent.system_prompt = prompt
4856
+
4857
+ def _override_tool_desc(self, event: BeforeToolCallEvent) -> None:
4858
+ config = BedrockAgentCoreContext.get_config_bundle()
4859
+ tool_descs = config.get("toolDescriptions", {})
4860
+
4861
+ tool_name = event.tool_use["name"]
4862
+ override = tool_descs.get(tool_name)
4863
+ if override and event.selected_tool:
4864
+ spec = event.selected_tool.tool_spec
4865
+ if spec and "description" in spec:
4866
+ spec["description"] = override
4867
+
4735
4868
  {{/if}}
4736
- """
4737
4869
 
4738
4870
  {{#if hasMemory}}
4739
4871
  def agent_factory():
@@ -4745,13 +4877,23 @@ def agent_factory():
4745
4877
  cache[key] = Agent(
4746
4878
  model=load_model(),
4747
4879
  session_manager=get_memory_session_manager(session_id, user_id),
4748
- system_prompt=SYSTEM_PROMPT,
4749
- tools=tools
4880
+ system_prompt=DEFAULT_SYSTEM_PROMPT,
4881
+ tools=tools{{#if hasConfigBundle}},
4882
+ hooks=[ConfigBundleHook()]{{/if}}
4750
4883
  )
4751
4884
  return cache[key]
4752
4885
  return get_or_create_agent
4753
4886
  get_or_create_agent = agent_factory()
4754
4887
  {{else}}
4888
+ {{#if hasConfigBundle}}
4889
+ def create_agent():
4890
+ return Agent(
4891
+ model=load_model(),
4892
+ system_prompt=DEFAULT_SYSTEM_PROMPT,
4893
+ tools=tools,
4894
+ hooks=[ConfigBundleHook()],
4895
+ )
4896
+ {{else}}
4755
4897
  _agent = None
4756
4898
 
4757
4899
  def get_or_create_agent():
@@ -4759,11 +4901,12 @@ def get_or_create_agent():
4759
4901
  if _agent is None:
4760
4902
  _agent = Agent(
4761
4903
  model=load_model(),
4762
- system_prompt=SYSTEM_PROMPT,
4904
+ system_prompt=DEFAULT_SYSTEM_PROMPT,
4763
4905
  tools=tools
4764
4906
  )
4765
4907
  return _agent
4766
4908
  {{/if}}
4909
+ {{/if}}
4767
4910
 
4768
4911
 
4769
4912
  @app.entrypoint
@@ -4774,8 +4917,12 @@ async def invoke(payload, context):
4774
4917
  session_id = getattr(context, 'session_id', 'default-session')
4775
4918
  user_id = getattr(context, 'user_id', 'default-user')
4776
4919
  agent = get_or_create_agent(session_id, user_id)
4920
+ {{else}}
4921
+ {{#if hasConfigBundle}}
4922
+ agent = create_agent()
4777
4923
  {{else}}
4778
4924
  agent = get_or_create_agent()
4925
+ {{/if}}
4779
4926
  {{/if}}
4780
4927
 
4781
4928
  # Execute and format response
@@ -5020,7 +5167,7 @@ requires-python = ">=3.10"
5020
5167
  dependencies = [
5021
5168
  {{#if (eq modelProvider "Anthropic")}}"anthropic >= 0.30.0",
5022
5169
  {{/if}}"aws-opentelemetry-distro",
5023
- "bedrock-agentcore >= 1.0.3",
5170
+ "bedrock-agentcore >= 1.9.1",
5024
5171
  "botocore[crt] >= 1.35.0",
5025
5172
  {{#if (eq modelProvider "Gemini")}}"google-genai >= 1.0.0",
5026
5173
  {{/if}}"mcp >= 1.19.0",
@@ -5042,6 +5189,7 @@ exports[`Assets Directory Snapshots > Python framework assets > python/python/ht
5042
5189
 
5043
5190
  exports[`Assets Directory Snapshots > Python framework assets > python/python/http/strands/capabilities/memory/session.py should match snapshot 1`] = `
5044
5191
  "import os
5192
+ import uuid
5045
5193
  from typing import Optional
5046
5194
 
5047
5195
  from bedrock_agentcore.memory.integrations.strands.config import AgentCoreMemoryConfig{{#if memoryProviders.[0].strategies.length}}, RetrievalConfig{{/if}}
@@ -5050,10 +5198,14 @@ from bedrock_agentcore.memory.integrations.strands.session_manager import AgentC
5050
5198
  MEMORY_ID = os.getenv("{{memoryProviders.[0].envVarName}}")
5051
5199
  REGION = os.getenv("AWS_REGION")
5052
5200
 
5053
- def get_memory_session_manager(session_id: str, actor_id: str) -> Optional[AgentCoreMemorySessionManager]:
5201
+ def get_memory_session_manager(session_id: Optional[str], actor_id: str) -> Optional[AgentCoreMemorySessionManager]:
5054
5202
  if not MEMORY_ID:
5055
5203
  return None
5056
5204
 
5205
+ # AgentCoreMemoryConfig rejects None; OAuth/CUSTOM_JWT callers can reach us
5206
+ # without a runtime session header, so synthesize one when absent.
5207
+ session_id = session_id or uuid.uuid4().hex
5208
+
5057
5209
  {{#if memoryProviders.[0].strategies.length}}
5058
5210
  retrieval_config = {
5059
5211
  {{#if (includes memoryProviders.[0].strategies "SEMANTIC")}}
@@ -5063,7 +5215,7 @@ def get_memory_session_manager(session_id: str, actor_id: str) -> Optional[Agent
5063
5215
  f"/users/{actor_id}/preferences": RetrievalConfig(top_k=3, relevance_score=0.5),
5064
5216
  {{/if}}
5065
5217
  {{#if (includes memoryProviders.[0].strategies "SUMMARIZATION")}}
5066
- f"/summaries/{actor_id}/{session_id}": RetrievalConfig(top_k=3, relevance_score=0.5),
5218
+ f"/summaries/{actor_id}": RetrievalConfig(top_k=3, relevance_score=0.5),
5067
5219
  {{/if}}
5068
5220
  }
5069
5221
  {{/if}}
@@ -5535,3 +5687,607 @@ When modifying JSON config files:
5535
5687
  `;
5536
5688
 
5537
5689
  exports[`Assets Directory Snapshots > TypeScript assets > typescript/typescript/.gitkeep should match snapshot 1`] = `""`;
5690
+
5691
+ exports[`Assets Directory Snapshots > TypeScript assets > typescript/typescript/http/strands/base/README.md should match snapshot 1`] = `
5692
+ "This is a project generated by the AgentCore CLI!
5693
+
5694
+ # Layout
5695
+
5696
+ The generated application code lives at the agent root directory. At the root, there is a \`.gitignore\` file, an
5697
+ \`agentcore/\` folder which represents the configurations and state associated with this project. Other \`agentcore\`
5698
+ commands like \`deploy\`, \`dev\`, and \`invoke\` rely on the configuration stored here.
5699
+
5700
+ ## Agent Root
5701
+
5702
+ The main entrypoint to your app is defined in \`main.ts\`. Using the AgentCore SDK \`BedrockAgentCoreApp\`, this file
5703
+ defines an HTTP server that streams tokens from your chosen Agent framework SDK.
5704
+
5705
+ \`model/load.ts\` instantiates your chosen model provider.
5706
+
5707
+ ## Environment Variables
5708
+
5709
+ | Variable | Required | Description |
5710
+ | --- | --- | --- |
5711
+ {{#if hasIdentity}}| \`{{identityProviders.[0].envVarName}}\` | Yes | {{modelProvider}} API key (local) or Identity provider name (deployed) |
5712
+ {{/if}}| \`LOCAL_DEV\` | No | Set to \`1\` to use \`.env.local\` instead of AgentCore Identity |
5713
+
5714
+ # Developing locally
5715
+
5716
+ If installation was successful, \`node_modules/\` is already populated with dependencies.
5717
+
5718
+ \`agentcore dev\` will start a local server using \`npx tsx watch main.ts\` for hot reload. The port is logged to the terminal (default \`8080\`).
5719
+
5720
+ In a new terminal, you can invoke that server with:
5721
+
5722
+ \`agentcore invoke --dev "What can you do"\`
5723
+
5724
+ # Deployment
5725
+
5726
+ After providing credentials, \`agentcore deploy\` will deploy your project into Amazon Bedrock AgentCore.
5727
+
5728
+ Use \`agentcore invoke\` to invoke your deployed agent.
5729
+ "
5730
+ `;
5731
+
5732
+ exports[`Assets Directory Snapshots > TypeScript assets > typescript/typescript/http/strands/base/gitignore.template should match snapshot 1`] = `
5733
+ "# Environment variables
5734
+ .env
5735
+ .env.*
5736
+
5737
+ # Node
5738
+ node_modules/
5739
+ dist/
5740
+ *.log
5741
+ npm-debug.log*
5742
+ yarn-debug.log*
5743
+ yarn-error.log*
5744
+
5745
+ # IDE
5746
+ .vscode/
5747
+ .idea/
5748
+ *.swp
5749
+ *.swo
5750
+ *~
5751
+
5752
+ # OS
5753
+ .DS_Store
5754
+ Thumbs.db
5755
+ "
5756
+ `;
5757
+
5758
+ exports[`Assets Directory Snapshots > TypeScript assets > typescript/typescript/http/strands/base/main.ts should match snapshot 1`] = `
5759
+ "import { BedrockAgentCoreApp } from 'bedrock-agentcore/runtime';
5760
+ import { Agent, McpClient, tool, type ToolList } from '@strands-agents/sdk';
5761
+ import { z } from 'zod';
5762
+ import { loadModel } from './model/load.js';
5763
+ import { getStreamableHttpMcpClient } from './mcp_client/client.js';
5764
+
5765
+ // Define a collection of MCP clients (filter out anything that failed to initialize)
5766
+ const mcpClients: McpClient[] = [getStreamableHttpMcpClient()].filter(
5767
+ (client): client is McpClient => Boolean(client)
5768
+ );
5769
+
5770
+ // Define a collection of tools used by the model
5771
+ const tools: ToolList = [];
5772
+
5773
+ // Define a simple function tool — the Zod schema gives us type inference and runtime validation for free
5774
+ const addNumbers = tool({
5775
+ name: 'add_numbers',
5776
+ description: 'Return the sum of two numbers',
5777
+ inputSchema: z.object({
5778
+ a: z.number(),
5779
+ b: z.number(),
5780
+ }),
5781
+ callback: async ({ a, b }) => a + b,
5782
+ });
5783
+ tools.push(addNumbers);
5784
+
5785
+ // Add MCP clients to tools
5786
+ tools.push(...mcpClients);
5787
+
5788
+ const SYSTEM_PROMPT = \`
5789
+ You are a helpful assistant. Use tools when appropriate.
5790
+ \`;
5791
+
5792
+ let cachedAgent: Agent | null = null;
5793
+
5794
+ async function getOrCreateAgent(): Promise<Agent> {
5795
+ if (!cachedAgent) {
5796
+ const model = await loadModel();
5797
+ cachedAgent = new Agent({
5798
+ model,
5799
+ systemPrompt: SYSTEM_PROMPT,
5800
+ tools,
5801
+ });
5802
+ }
5803
+ return cachedAgent;
5804
+ }
5805
+
5806
+ const app = new BedrockAgentCoreApp({
5807
+ invocationHandler: {
5808
+ async *process(payload: any, context: any) {
5809
+ const agent = await getOrCreateAgent();
5810
+
5811
+ for await (const event of agent.stream(payload.prompt ?? '')) {
5812
+ if (
5813
+ event.type === 'modelStreamUpdateEvent' &&
5814
+ event.event?.type === 'modelContentBlockDeltaEvent' &&
5815
+ event.event.delta?.type === 'textDelta'
5816
+ ) {
5817
+ yield { data: event.event.delta.text };
5818
+ }
5819
+ }
5820
+ },
5821
+ },
5822
+ });
5823
+
5824
+ app.run({ port: parseInt(process.env.PORT ?? '8080') });
5825
+ "
5826
+ `;
5827
+
5828
+ exports[`Assets Directory Snapshots > TypeScript assets > typescript/typescript/http/strands/base/mcp_client/client.ts should match snapshot 1`] = `
5829
+ "import { McpClient } from '@strands-agents/sdk';
5830
+ import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
5831
+
5832
+ // ExaAI provides information about code through web searches, crawling and code context searches through their platform. Requires no authentication
5833
+ const EXAMPLE_MCP_ENDPOINT = 'https://mcp.exa.ai/mcp';
5834
+
5835
+ export function getStreamableHttpMcpClient(): McpClient {
5836
+ // to use an MCP server that supports bearer authentication, add a headers() callback to requestInit
5837
+ const transport = new StreamableHTTPClientTransport(new URL(EXAMPLE_MCP_ENDPOINT));
5838
+ return new McpClient({ transport });
5839
+ }
5840
+ "
5841
+ `;
5842
+
5843
+ exports[`Assets Directory Snapshots > TypeScript assets > typescript/typescript/http/strands/base/model/load.ts should match snapshot 1`] = `
5844
+ "{{#if (eq modelProvider "Bedrock")}}
5845
+ import { BedrockModel } from '@strands-agents/sdk/models/bedrock';
5846
+
5847
+ export function loadModel(): BedrockModel {
5848
+ return new BedrockModel({ modelId: 'global.anthropic.claude-sonnet-4-5-20250929-v1:0' });
5849
+ }
5850
+ {{/if}}
5851
+ {{#if (eq modelProvider "Anthropic")}}
5852
+ import { AnthropicModel } from '@strands-agents/sdk/models/anthropic';
5853
+ import { withApiKey } from 'bedrock-agentcore/identity';
5854
+
5855
+ const IDENTITY_PROVIDER_NAME = '{{identityProviders.[0].name}}';
5856
+ const IDENTITY_ENV_VAR = '{{identityProviders.[0].envVarName}}';
5857
+
5858
+ async function getApiKey(): Promise<string> {
5859
+ if (process.env.LOCAL_DEV === '1') {
5860
+ const apiKey = process.env[IDENTITY_ENV_VAR] ?? process.env.ANTHROPIC_API_KEY;
5861
+ if (!apiKey) {
5862
+ throw new Error(\`\${IDENTITY_ENV_VAR} or ANTHROPIC_API_KEY not found. Add your key to agentcore/.env.local\`);
5863
+ }
5864
+ return apiKey;
5865
+ }
5866
+ return withApiKey({ providerName: IDENTITY_PROVIDER_NAME })(async (apiKey: string) => apiKey)();
5867
+ }
5868
+
5869
+ let _model: AnthropicModel | undefined;
5870
+
5871
+ export async function loadModel(): Promise<AnthropicModel> {
5872
+ if (!_model) {
5873
+ const apiKey = await getApiKey();
5874
+ _model = new AnthropicModel({
5875
+ apiKey,
5876
+ modelId: 'claude-sonnet-4-5-20250929',
5877
+ maxTokens: 5000,
5878
+ });
5879
+ }
5880
+ return _model;
5881
+ }
5882
+ {{/if}}
5883
+ {{#if (eq modelProvider "OpenAI")}}
5884
+ import { OpenAIModel } from '@strands-agents/sdk/models/openai';
5885
+ import { withApiKey } from 'bedrock-agentcore/identity';
5886
+
5887
+ const IDENTITY_PROVIDER_NAME = '{{identityProviders.[0].name}}';
5888
+ const IDENTITY_ENV_VAR = '{{identityProviders.[0].envVarName}}';
5889
+
5890
+ async function getApiKey(): Promise<string> {
5891
+ if (process.env.LOCAL_DEV === '1') {
5892
+ const apiKey = process.env[IDENTITY_ENV_VAR] ?? process.env.OPENAI_API_KEY;
5893
+ if (!apiKey) {
5894
+ throw new Error(\`\${IDENTITY_ENV_VAR} or OPENAI_API_KEY not found. Add your key to agentcore/.env.local\`);
5895
+ }
5896
+ return apiKey;
5897
+ }
5898
+ return withApiKey({ providerName: IDENTITY_PROVIDER_NAME })(async (apiKey: string) => apiKey)();
5899
+ }
5900
+
5901
+ let _model: OpenAIModel | undefined;
5902
+
5903
+ export async function loadModel(): Promise<OpenAIModel> {
5904
+ if (!_model) {
5905
+ const apiKey = await getApiKey();
5906
+ _model = new OpenAIModel({
5907
+ api: 'chat',
5908
+ apiKey,
5909
+ modelId: 'gpt-4.1',
5910
+ });
5911
+ }
5912
+ return _model;
5913
+ }
5914
+ {{/if}}
5915
+ {{#if (eq modelProvider "Gemini")}}
5916
+ import { GoogleModel } from '@strands-agents/sdk/models/google';
5917
+ import { withApiKey } from 'bedrock-agentcore/identity';
5918
+
5919
+ const IDENTITY_PROVIDER_NAME = '{{identityProviders.[0].name}}';
5920
+ const IDENTITY_ENV_VAR = '{{identityProviders.[0].envVarName}}';
5921
+
5922
+ async function getApiKey(): Promise<string> {
5923
+ if (process.env.LOCAL_DEV === '1') {
5924
+ const apiKey = process.env[IDENTITY_ENV_VAR] ?? process.env.GEMINI_API_KEY;
5925
+ if (!apiKey) {
5926
+ throw new Error(\`\${IDENTITY_ENV_VAR} or GEMINI_API_KEY not found. Add your key to agentcore/.env.local\`);
5927
+ }
5928
+ return apiKey;
5929
+ }
5930
+ return withApiKey({ providerName: IDENTITY_PROVIDER_NAME })(async (apiKey: string) => apiKey)();
5931
+ }
5932
+
5933
+ let _model: GoogleModel | undefined;
5934
+
5935
+ export async function loadModel(): Promise<GoogleModel> {
5936
+ if (!_model) {
5937
+ const apiKey = await getApiKey();
5938
+ _model = new GoogleModel({
5939
+ apiKey,
5940
+ modelId: 'gemini-2.5-flash',
5941
+ });
5942
+ }
5943
+ return _model;
5944
+ }
5945
+ {{/if}}
5946
+ "
5947
+ `;
5948
+
5949
+ exports[`Assets Directory Snapshots > TypeScript assets > typescript/typescript/http/strands/base/package.json should match snapshot 1`] = `
5950
+ "{
5951
+ "name": "{{name}}",
5952
+ "version": "0.1.0",
5953
+ "description": "AgentCore Runtime Application using Strands TypeScript SDK",
5954
+ "private": true,
5955
+ "type": "module",
5956
+ "scripts": {
5957
+ "build": "tsc",
5958
+ "start": "node dist/main.js",
5959
+ "dev": "tsx watch main.ts"
5960
+ },
5961
+ "dependencies": {
5962
+ {{#if (eq modelProvider "Anthropic")}}
5963
+ "@anthropic-ai/sdk": "^0.71.2",
5964
+ {{/if}}
5965
+ {{#if (eq modelProvider "OpenAI")}}
5966
+ "openai": "^6.7.0",
5967
+ {{/if}}
5968
+ {{#if (eq modelProvider "Gemini")}}
5969
+ "@google/genai": "^1.40.0",
5970
+ {{/if}}
5971
+ "@modelcontextprotocol/sdk": "^1.25.2",
5972
+ "@strands-agents/sdk": "1.0.0-rc.4",
5973
+ "bedrock-agentcore": "^0.2.4",
5974
+ "tsx": "^4.19.0",
5975
+ "zod": "^4.4.3"
5976
+ },
5977
+ "devDependencies": {
5978
+ "@types/node": "^22.0.0",
5979
+ "typescript": "^5.6.0"
5980
+ },
5981
+ "overrides": {
5982
+ "bedrock-agentcore": {
5983
+ "@strands-agents/sdk": "$@strands-agents/sdk"
5984
+ }
5985
+ }
5986
+ }
5987
+ "
5988
+ `;
5989
+
5990
+ exports[`Assets Directory Snapshots > TypeScript assets > typescript/typescript/http/strands/base/tsconfig.json should match snapshot 1`] = `
5991
+ "{
5992
+ "compilerOptions": {
5993
+ "target": "ES2022",
5994
+ "module": "NodeNext",
5995
+ "moduleResolution": "NodeNext",
5996
+ "strict": true,
5997
+ "esModuleInterop": true,
5998
+ "skipLibCheck": true,
5999
+ "forceConsistentCasingInFileNames": true,
6000
+ "resolveJsonModule": true,
6001
+ "declaration": false,
6002
+ "sourceMap": true,
6003
+ "outDir": "dist",
6004
+ "rootDir": ".",
6005
+ "types": ["node"]
6006
+ },
6007
+ "include": ["**/*.ts"],
6008
+ "exclude": ["node_modules", "dist"]
6009
+ }
6010
+ "
6011
+ `;
6012
+
6013
+ exports[`Assets Directory Snapshots > TypeScript assets > typescript/typescript/http/vercelai/base/README.md should match snapshot 1`] = `
6014
+ "This is a project generated by the AgentCore CLI!
6015
+
6016
+ # Layout
6017
+
6018
+ The generated application code lives at the agent root directory. At the root, there is a \`.gitignore\` file, an
6019
+ \`agentcore/\` folder which represents the configurations and state associated with this project. Other \`agentcore\`
6020
+ commands like \`deploy\`, \`dev\`, and \`invoke\` rely on the configuration stored here.
6021
+
6022
+ ## Agent Root
6023
+
6024
+ The main entrypoint to your app is defined in \`main.ts\`. Using the AgentCore SDK \`BedrockAgentCoreApp\`, this file
6025
+ defines an HTTP app that streams tokens using the Vercel AI SDK's \`streamText\` API.
6026
+
6027
+ \`model/load.ts\` instantiates your chosen model provider.
6028
+
6029
+ ## Environment Variables
6030
+
6031
+ | Variable | Required | Description |
6032
+ | --- | --- | --- |
6033
+ {{#if hasIdentity}}| \`{{identityProviders.[0].envVarName}}\` | Yes | {{modelProvider}} API key (local) or Identity provider name (deployed) |
6034
+ {{/if}}| \`LOCAL_DEV\` | No | Set to \`1\` to use \`.env.local\` instead of AgentCore Identity |
6035
+
6036
+ # Developing locally
6037
+
6038
+ If installation was successful, \`node_modules/\` is already populated with dependencies.
6039
+
6040
+ \`agentcore dev\` will start a local server using \`npx tsx watch main.ts\` for hot reload. The port is logged to the terminal (default \`8080\`).
6041
+
6042
+ In a new terminal, you can invoke that server with:
6043
+
6044
+ \`agentcore invoke --dev "What can you do"\`
6045
+
6046
+ # Deployment
6047
+
6048
+ After providing credentials, \`agentcore deploy\` will deploy your project into Amazon Bedrock AgentCore.
6049
+
6050
+ Use \`agentcore invoke\` to invoke your deployed agent.
6051
+ "
6052
+ `;
6053
+
6054
+ exports[`Assets Directory Snapshots > TypeScript assets > typescript/typescript/http/vercelai/base/gitignore.template should match snapshot 1`] = `
6055
+ "# Environment variables
6056
+ .env
6057
+ .env.*
6058
+
6059
+ # Node
6060
+ node_modules/
6061
+ dist/
6062
+ *.log
6063
+ npm-debug.log*
6064
+ yarn-debug.log*
6065
+ yarn-error.log*
6066
+
6067
+ # IDE
6068
+ .vscode/
6069
+ .idea/
6070
+ *.swp
6071
+ *.swo
6072
+ *~
6073
+
6074
+ # OS
6075
+ .DS_Store
6076
+ Thumbs.db
6077
+ "
6078
+ `;
6079
+
6080
+ exports[`Assets Directory Snapshots > TypeScript assets > typescript/typescript/http/vercelai/base/main.ts should match snapshot 1`] = `
6081
+ "import { BedrockAgentCoreApp } from 'bedrock-agentcore/runtime';
6082
+ import { streamText } from 'ai';
6083
+ import { loadModel } from './model/load.js';
6084
+
6085
+ const SYSTEM_PROMPT = \`You are a helpful assistant.\`;
6086
+
6087
+ const app = new BedrockAgentCoreApp({
6088
+ invocationHandler: {
6089
+ async *process(payload: any, context: any) {
6090
+ const model = await loadModel();
6091
+ const result = streamText({
6092
+ model,
6093
+ system: SYSTEM_PROMPT,
6094
+ prompt: payload.prompt ?? '',
6095
+ });
6096
+
6097
+ for await (const chunk of result.textStream) {
6098
+ yield { data: chunk };
6099
+ }
6100
+ },
6101
+ },
6102
+ });
6103
+
6104
+ app.run({ port: parseInt(process.env.PORT ?? '8080') });
6105
+ "
6106
+ `;
6107
+
6108
+ exports[`Assets Directory Snapshots > TypeScript assets > typescript/typescript/http/vercelai/base/model/load.ts should match snapshot 1`] = `
6109
+ "{{#if (eq modelProvider "Bedrock")}}
6110
+ import { createAmazonBedrock } from '@ai-sdk/amazon-bedrock';
6111
+ import { fromNodeProviderChain } from '@aws-sdk/credential-providers';
6112
+
6113
+ const provider = fromNodeProviderChain();
6114
+
6115
+ const bedrock = createAmazonBedrock({
6116
+ region: process.env.AWS_REGION ?? 'us-east-1',
6117
+ credentialProvider: async () => {
6118
+ const creds = await provider();
6119
+ return {
6120
+ accessKeyId: creds.accessKeyId,
6121
+ secretAccessKey: creds.secretAccessKey,
6122
+ sessionToken: creds.sessionToken,
6123
+ };
6124
+ },
6125
+ });
6126
+
6127
+ export function loadModel() {
6128
+ return bedrock('us.anthropic.claude-sonnet-4-5-20250929-v1:0');
6129
+ }
6130
+ {{/if}}
6131
+ {{#if (eq modelProvider "Anthropic")}}
6132
+ import { createAnthropic } from '@ai-sdk/anthropic';
6133
+ import { withApiKey } from 'bedrock-agentcore/identity';
6134
+
6135
+ const IDENTITY_PROVIDER_NAME = '{{identityProviders.[0].name}}';
6136
+ const IDENTITY_ENV_VAR = '{{identityProviders.[0].envVarName}}';
6137
+
6138
+ async function getApiKey(): Promise<string> {
6139
+ if (process.env.LOCAL_DEV === '1') {
6140
+ const apiKey = process.env[IDENTITY_ENV_VAR] ?? process.env.ANTHROPIC_API_KEY;
6141
+ if (!apiKey) {
6142
+ throw new Error(\`\${IDENTITY_ENV_VAR} or ANTHROPIC_API_KEY not found. Add your key to agentcore/.env.local\`);
6143
+ }
6144
+ return apiKey;
6145
+ }
6146
+ return withApiKey({ providerName: IDENTITY_PROVIDER_NAME })(async (apiKey: string) => apiKey)();
6147
+ }
6148
+
6149
+ let _anthropic: ReturnType<typeof createAnthropic> | undefined;
6150
+
6151
+ async function getProvider() {
6152
+ if (!_anthropic) {
6153
+ const apiKey = await getApiKey();
6154
+ _anthropic = createAnthropic({ apiKey });
6155
+ }
6156
+ return _anthropic;
6157
+ }
6158
+
6159
+ export async function loadModel() {
6160
+ const anthropic = await getProvider();
6161
+ return anthropic('claude-sonnet-4-5-20250929');
6162
+ }
6163
+ {{/if}}
6164
+ {{#if (eq modelProvider "OpenAI")}}
6165
+ import { createOpenAI } from '@ai-sdk/openai';
6166
+ import { withApiKey } from 'bedrock-agentcore/identity';
6167
+
6168
+ const IDENTITY_PROVIDER_NAME = '{{identityProviders.[0].name}}';
6169
+ const IDENTITY_ENV_VAR = '{{identityProviders.[0].envVarName}}';
6170
+
6171
+ async function getApiKey(): Promise<string> {
6172
+ if (process.env.LOCAL_DEV === '1') {
6173
+ const apiKey = process.env[IDENTITY_ENV_VAR] ?? process.env.OPENAI_API_KEY;
6174
+ if (!apiKey) {
6175
+ throw new Error(\`\${IDENTITY_ENV_VAR} or OPENAI_API_KEY not found. Add your key to agentcore/.env.local\`);
6176
+ }
6177
+ return apiKey;
6178
+ }
6179
+ return withApiKey({ providerName: IDENTITY_PROVIDER_NAME })(async (apiKey: string) => apiKey)();
6180
+ }
6181
+
6182
+ let _openai: ReturnType<typeof createOpenAI> | undefined;
6183
+
6184
+ async function getProvider() {
6185
+ if (!_openai) {
6186
+ const apiKey = await getApiKey();
6187
+ _openai = createOpenAI({ apiKey });
6188
+ }
6189
+ return _openai;
6190
+ }
6191
+
6192
+ export async function loadModel() {
6193
+ const openai = await getProvider();
6194
+ return openai('gpt-4.1');
6195
+ }
6196
+ {{/if}}
6197
+ {{#if (eq modelProvider "Gemini")}}
6198
+ import { createGoogleGenerativeAI } from '@ai-sdk/google';
6199
+ import { withApiKey } from 'bedrock-agentcore/identity';
6200
+
6201
+ const IDENTITY_PROVIDER_NAME = '{{identityProviders.[0].name}}';
6202
+ const IDENTITY_ENV_VAR = '{{identityProviders.[0].envVarName}}';
6203
+
6204
+ async function getApiKey(): Promise<string> {
6205
+ if (process.env.LOCAL_DEV === '1') {
6206
+ const apiKey = process.env[IDENTITY_ENV_VAR] ?? process.env.GEMINI_API_KEY;
6207
+ if (!apiKey) {
6208
+ throw new Error(\`\${IDENTITY_ENV_VAR} or GEMINI_API_KEY not found. Add your key to agentcore/.env.local\`);
6209
+ }
6210
+ return apiKey;
6211
+ }
6212
+ return withApiKey({ providerName: IDENTITY_PROVIDER_NAME })(async (apiKey: string) => apiKey)();
6213
+ }
6214
+
6215
+ let _google: ReturnType<typeof createGoogleGenerativeAI> | undefined;
6216
+
6217
+ async function getProvider() {
6218
+ if (!_google) {
6219
+ const apiKey = await getApiKey();
6220
+ _google = createGoogleGenerativeAI({ apiKey });
6221
+ }
6222
+ return _google;
6223
+ }
6224
+
6225
+ export async function loadModel() {
6226
+ const google = await getProvider();
6227
+ return google('gemini-2.5-flash');
6228
+ }
6229
+ {{/if}}
6230
+ "
6231
+ `;
6232
+
6233
+ exports[`Assets Directory Snapshots > TypeScript assets > typescript/typescript/http/vercelai/base/package.json should match snapshot 1`] = `
6234
+ "{
6235
+ "name": "{{name}}",
6236
+ "version": "0.1.0",
6237
+ "description": "AgentCore Runtime Application using Vercel AI SDK",
6238
+ "private": true,
6239
+ "type": "module",
6240
+ "scripts": {
6241
+ "build": "tsc",
6242
+ "start": "node dist/main.js",
6243
+ "dev": "tsx watch main.ts"
6244
+ },
6245
+ "dependencies": {
6246
+ "ai": "^6.0.0",
6247
+ {{#if (eq modelProvider "Bedrock")}}
6248
+ "@ai-sdk/amazon-bedrock": "^4.0.0",
6249
+ "@aws-sdk/credential-providers": "^3.0.0",
6250
+ {{/if}}
6251
+ {{#if (eq modelProvider "Anthropic")}}
6252
+ "@ai-sdk/anthropic": "^3.0.0",
6253
+ {{/if}}
6254
+ {{#if (eq modelProvider "OpenAI")}}
6255
+ "@ai-sdk/openai": "^3.0.0",
6256
+ {{/if}}
6257
+ {{#if (eq modelProvider "Gemini")}}
6258
+ "@ai-sdk/google": "^3.0.0",
6259
+ {{/if}}
6260
+ "bedrock-agentcore": "^0.2.4",
6261
+ "tsx": "^4.19.0",
6262
+ "zod": "^3.24.0"
6263
+ },
6264
+ "devDependencies": {
6265
+ "@types/node": "^22.0.0",
6266
+ "typescript": "^5.6.0"
6267
+ }
6268
+ }
6269
+ "
6270
+ `;
6271
+
6272
+ exports[`Assets Directory Snapshots > TypeScript assets > typescript/typescript/http/vercelai/base/tsconfig.json should match snapshot 1`] = `
6273
+ "{
6274
+ "compilerOptions": {
6275
+ "target": "ES2022",
6276
+ "module": "NodeNext",
6277
+ "moduleResolution": "NodeNext",
6278
+ "strict": true,
6279
+ "esModuleInterop": true,
6280
+ "skipLibCheck": true,
6281
+ "forceConsistentCasingInFileNames": true,
6282
+ "resolveJsonModule": true,
6283
+ "declaration": false,
6284
+ "sourceMap": true,
6285
+ "outDir": "dist",
6286
+ "rootDir": ".",
6287
+ "types": ["node"]
6288
+ },
6289
+ "include": ["**/*.ts"],
6290
+ "exclude": ["node_modules", "dist"]
6291
+ }
6292
+ "
6293
+ `;