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

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