@aws/nx-plugin 1.0.0-rc.17 → 1.0.0-rc.19

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 (110) hide show
  1. package/generators.json +9 -1
  2. package/package.json +1 -1
  3. package/src/agentcore-gateway/attach-upstream.d.ts +33 -0
  4. package/src/agentcore-gateway/attach-upstream.js +41 -0
  5. package/src/agentcore-gateway/attach-upstream.js.map +1 -0
  6. package/src/agentcore-gateway/files/project/serve-local.ts.template +3 -2
  7. package/src/agentcore-gateway/gateway-connection/generator.d.ts +21 -0
  8. package/src/agentcore-gateway/gateway-connection/generator.js +102 -0
  9. package/src/agentcore-gateway/gateway-connection/generator.js.map +1 -0
  10. package/src/agentcore-gateway/gateway-connection/schema.d.ts +12 -0
  11. package/src/agentcore-gateway/gateway-connection/schema.json +26 -0
  12. package/src/agentcore-gateway/mcp-connection/generator.js +8 -24
  13. package/src/agentcore-gateway/mcp-connection/generator.js.map +1 -1
  14. package/src/connection/generator.js +66 -63
  15. package/src/connection/generator.js.map +1 -1
  16. package/src/license/generator.js +8 -19
  17. package/src/license/generator.js.map +1 -1
  18. package/src/license/known-exceptions.d.ts +0 -1
  19. package/src/license/known-exceptions.js +1 -8
  20. package/src/license/known-exceptions.js.map +1 -1
  21. package/src/py/agent/__snapshots__/generator.spec.ts.snap +15 -6
  22. package/src/py/agent/a2a-connection/__snapshots__/generator.spec.ts.snap +201 -0
  23. package/src/py/agent/a2a-connection/files/agent-connection/app/{__targetAgentSnakeCase___client.py.template → __targetAgentSnakeCase___client_strands.py.template} +7 -5
  24. package/src/py/agent/a2a-connection/generator.js +6 -5
  25. package/src/py/agent/a2a-connection/generator.js.map +1 -1
  26. package/src/py/agent/files/http/main.py.template +2 -2
  27. package/src/py/agent/gateway-connection/__snapshots__/generator.spec.ts.snap +197 -0
  28. package/src/py/agent/gateway-connection/files/agent-connection/app/{__gatewaySnakeCase___client.py.template → __gatewaySnakeCase___client_strands.py.template} +6 -6
  29. package/src/py/agent/gateway-connection/generator.js +5 -5
  30. package/src/py/agent/gateway-connection/generator.js.map +1 -1
  31. package/src/py/agent/generator.js +3 -5
  32. package/src/py/agent/generator.js.map +1 -1
  33. package/src/py/agent/mcp-connection/__snapshots__/generator.spec.ts.snap +157 -79
  34. package/src/py/agent/mcp-connection/files/agent-connection/app/{__mcpServerSnakeCase___client.py.template → __mcpServerSnakeCase___client_strands.py.template} +7 -5
  35. package/src/py/agent/mcp-connection/generator.js +5 -5
  36. package/src/py/agent/mcp-connection/generator.js.map +1 -1
  37. package/src/py/fast-api/__snapshots__/generator.spec.ts.snap +37 -3
  38. package/src/py/fast-api/files/app/__name__/main.py.template +4 -1
  39. package/src/py/mcp-server/__snapshots__/generator.spec.ts.snap +13 -4
  40. package/src/smithy/project/__snapshots__/generator.spec.ts.snap +1 -0
  41. package/src/smithy/project/files/src/operations/echo.smithy.template +1 -0
  42. package/src/terraform/project/files/application/src/main.tf.template +6 -1
  43. package/src/trpc/backend/__snapshots__/generator.spec.ts.snap +35 -4
  44. package/src/trpc/backend/files/src/procedures/echo.ts.template +1 -1
  45. package/src/trpc/backend/files/src/schema/echo.ts.template +2 -2
  46. package/src/ts/agent/__snapshots__/generator.spec.ts.snap +14 -5
  47. package/src/ts/agent/a2a-connection/__snapshots__/generator.spec.ts.snap +256 -0
  48. package/src/ts/agent/a2a-connection/files/agent-connection/app/{__targetAgentKebabCase__-client.ts.template → __targetAgentKebabCase__-client-strands.ts.template} +5 -5
  49. package/src/ts/agent/a2a-connection/generator.js +3 -3
  50. package/src/ts/agent/a2a-connection/generator.js.map +1 -1
  51. package/src/ts/agent/files/http/router.ts.template +1 -1
  52. package/src/ts/agent/gateway-connection/__snapshots__/generator.spec.ts.snap +220 -0
  53. package/src/ts/agent/gateway-connection/files/agent-connection/app/{__gatewayKebabCase__-client.ts.template → __gatewayKebabCase__-client-strands.ts.template} +5 -5
  54. package/src/ts/agent/gateway-connection/generator.js +3 -3
  55. package/src/ts/agent/gateway-connection/generator.js.map +1 -1
  56. package/src/ts/agent/generator.js +3 -0
  57. package/src/ts/agent/generator.js.map +1 -1
  58. package/src/ts/agent/mcp-connection/__snapshots__/generator.spec.ts.snap +183 -110
  59. package/src/ts/agent/mcp-connection/files/agent-connection/app/{__mcpServerKebabCase__-client.ts.template → __mcpServerKebabCase__-client-strands.ts.template} +5 -5
  60. package/src/ts/agent/mcp-connection/generator.js +3 -3
  61. package/src/ts/agent/mcp-connection/generator.js.map +1 -1
  62. package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +13 -4
  63. package/src/ts/rdb/__snapshots__/generator.spec.ts.snap +64 -24
  64. package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +13 -4
  65. package/src/ts/react-website/cognito-auth/__snapshots__/generator.terraform.spec.ts.snap +9 -3
  66. package/src/utils/agent-connection/agent-connection.d.ts +50 -24
  67. package/src/utils/agent-connection/agent-connection.js +137 -45
  68. package/src/utils/agent-connection/agent-connection.js.map +1 -1
  69. package/src/utils/agent-connection/files/core-a2a/agentcore-a2a-client-config.ts.template +93 -0
  70. package/src/utils/agent-connection/files/core-auth/agentcore-endpoints.ts.template +37 -0
  71. package/src/utils/agent-connection/files/core-auth/agentcore-fetch.ts.template +54 -0
  72. package/src/utils/agent-connection/files/core-gateway/agentcore-gateway-mcp-transport.ts.template +41 -0
  73. package/src/utils/agent-connection/files/core-mcp/agentcore-mcp-transport.ts.template +70 -0
  74. package/src/utils/agent-connection/files/core-shared/agentcore-transport.ts.template +39 -0
  75. package/src/utils/agent-connection/files/core-strands/a2a/agentcore-a2a-client-strands.ts.template +61 -0
  76. package/src/utils/agent-connection/files/core-strands/gateway/agentcore-gateway-mcp-client-strands.ts.template +26 -0
  77. package/src/utils/agent-connection/files/core-strands/mcp/agentcore-mcp-client-strands.ts.template +27 -0
  78. package/src/utils/agent-connection/files/py-core-a2a/agentcore_a2a_client_config.py.template +43 -0
  79. package/src/utils/agent-connection/files/py-core-auth/agentcore_endpoints.py.template +47 -0
  80. package/src/utils/agent-connection/files/py-core-auth/auth/session.py.template +51 -0
  81. package/src/utils/agent-connection/files/py-core-gateway/agentcore_gateway_mcp_transport.py.template +28 -0
  82. package/src/utils/agent-connection/files/py-core-mcp/agentcore_mcp_transport.py.template +34 -0
  83. package/src/utils/agent-connection/files/py-core-shared/agentcore_transport.py.template +40 -0
  84. package/src/utils/agent-connection/files/py-core-strands/a2a/agentcore_a2a_client_strands.py.template +66 -0
  85. package/src/utils/agent-connection/files/py-core-strands/gateway/agentcore_gateway_mcp_client_strands.py.template +22 -0
  86. package/src/utils/agent-connection/files/py-core-strands/mcp/agentcore_mcp_client_strands.py.template +30 -0
  87. package/src/utils/agent-core-constructs/files/cdk/app/agentcore-gateway/__nameKebabCase__/__nameKebabCase__.ts.template +3 -0
  88. package/src/utils/agent-core-constructs/files/cdk/core/agentcore-gateway/agentcore-gateway.ts.template +110 -28
  89. package/src/utils/agent-core-constructs/files/terraform/app/agentcore-gateway/__nameKebabCase__/__nameKebabCase__.tf.template +95 -2
  90. package/src/utils/agent-core-constructs/files/terraform/core/agent-core/runtime.tf.template +13 -4
  91. package/src/utils/api-constructs/files/cdk/core/api/http/http-api.ts.template +9 -0
  92. package/src/utils/api-constructs/files/cdk/core/api/rest/rest-api.ts.template +23 -1
  93. package/src/utils/files/terraform/src/core/runtime-config/appconfig-deployment/appconfig-deployment.tf.template +9 -3
  94. package/src/utils/files/terraform/src/core/runtime-config/read/read.tf.template +7 -2
  95. package/src/utils/identity-constructs/files/terraform/core/user-identity/add-callback-url/add-callback-url.tf.template +9 -3
  96. package/src/utils/rdb-constructs/files/terraform/app/dbs/__nameKebabCase__/__nameKebabCase__.tf.template +22 -8
  97. package/src/utils/rdb-constructs/files/terraform/core/rdb/aurora/aurora.tf.template +10 -4
  98. package/src/utils/versions.d.ts +1 -1
  99. package/src/utils/versions.js +1 -1
  100. package/src/utils/website-constructs/files/terraform/core/static-website/static-website.tf.template +13 -4
  101. package/src/utils/agent-connection/files/core-a2a/agentcore-a2a-client.ts.template +0 -123
  102. package/src/utils/agent-connection/files/core-gateway/agentcore-gateway-mcp-client.ts.template +0 -78
  103. package/src/utils/agent-connection/files/core-mcp/agentcore-mcp-client.ts.template +0 -128
  104. package/src/utils/agent-connection/files/py-core-a2a/agentcore_a2a_client.py.template +0 -120
  105. package/src/utils/agent-connection/files/py-core-gateway/agentcore_gateway_mcp_client.py.template +0 -78
  106. package/src/utils/agent-connection/files/py-core-mcp/agentcore_mcp_client.py.template +0 -89
  107. /package/src/utils/agent-connection/files/{core-runtime-config/model-errors.ts.template → core-strands/base/model-errors-strands.ts.template} +0 -0
  108. /package/src/utils/agent-connection/files/{core-runtime-config/with-session-id.ts.template → core-strands/base/with-session-id-strands.ts.template} +0 -0
  109. /package/src/utils/agent-connection/files/{py-core-runtime-config/model_errors.py.template → py-core-strands/base/model_errors_strands.py.template} +0 -0
  110. /package/src/utils/agent-connection/files/{py-core-runtime-config/with_session_id.py.template → py-core-strands/base/with_session_id_strands.py.template} +0 -0
@@ -1336,9 +1336,9 @@ resource "null_resource" "proxy_target_ready" {
1336
1336
  deadline=$((start_time + 600))
1337
1337
  while true; do
1338
1338
  target_state=$(aws rds describe-db-proxy-targets \\
1339
- --region \${data.aws_region.current.region} \\
1340
- --db-proxy-name \${self.triggers.db_proxy_name} \\
1341
- --target-group-name \${self.triggers.target_group_name} \\
1339
+ --region "$AWS_REGION" \\
1340
+ --db-proxy-name "$DB_PROXY_NAME" \\
1341
+ --target-group-name "$TARGET_GROUP_NAME" \\
1342
1342
  --query "Targets[?Type=='RDS_INSTANCE'] | [0].TargetHealth.State" \\
1343
1343
  --output text)
1344
1344
 
@@ -1348,13 +1348,19 @@ resource "null_resource" "proxy_target_ready" {
1348
1348
 
1349
1349
  current_time=$(date +%s)
1350
1350
  if [ "$current_time" -ge "$deadline" ]; then
1351
- echo "RDS Proxy target \${self.triggers.db_cluster_identifier} did not become AVAILABLE within 10 minutes. Last state: $target_state"
1351
+ echo "RDS Proxy target $DB_CLUSTER_IDENTIFIER did not become AVAILABLE within 10 minutes. Last state: $target_state"
1352
1352
  exit 1
1353
1353
  fi
1354
1354
 
1355
1355
  sleep 10
1356
1356
  done
1357
1357
  EOT
1358
+ environment = {
1359
+ AWS_REGION = data.aws_region.current.region
1360
+ DB_PROXY_NAME = self.triggers.db_proxy_name
1361
+ TARGET_GROUP_NAME = self.triggers.target_group_name
1362
+ DB_CLUSTER_IDENTIFIER = self.triggers.db_cluster_identifier
1363
+ }
1358
1364
  }
1359
1365
 
1360
1366
  depends_on = [
@@ -1838,10 +1844,15 @@ resource "null_resource" "docker_publish" {
1838
1844
 
1839
1845
  provisioner "local-exec" {
1840
1846
  command = <<-EOT
1841
- aws ecr get-login-password --region \${data.aws_region.current.region} | docker login --username AWS --password-stdin \${self.triggers.repository_url}
1842
- docker tag \${self.triggers.docker_image_tag} \${self.triggers.repository_url}:latest
1843
- docker push \${self.triggers.repository_url}:latest
1847
+ aws ecr get-login-password --region "$AWS_REGION" | docker login --username AWS --password-stdin "$REPOSITORY_URL"
1848
+ docker tag "$DOCKER_IMAGE_TAG" "$REPOSITORY_URL:latest"
1849
+ docker push "$REPOSITORY_URL:latest"
1844
1850
  EOT
1851
+ environment = {
1852
+ AWS_REGION = data.aws_region.current.region
1853
+ REPOSITORY_URL = self.triggers.repository_url
1854
+ DOCKER_IMAGE_TAG = self.triggers.docker_image_tag
1855
+ }
1845
1856
  }
1846
1857
 
1847
1858
  depends_on = [aws_ecr_repository_policy.migration_handler]
@@ -2099,10 +2110,10 @@ resource "null_resource" "create_db_user_trigger" {
2099
2110
  command = <<-EOT
2100
2111
  output_file=$(mktemp)
2101
2112
  response=$(aws lambda invoke \\
2102
- --region \${data.aws_region.current.region} \\
2103
- --function-name \${self.triggers.function_name} \\
2113
+ --region "$AWS_REGION" \\
2114
+ --function-name "$FUNCTION_NAME" \\
2104
2115
  --cli-binary-format raw-in-base64-out \\
2105
- --payload '{"RequestType":"Create","PhysicalResourceId":"db-user:\${self.triggers.db_user}"}' \\
2116
+ --payload "{\\"RequestType\\":\\"Create\\",\\"PhysicalResourceId\\":\\"db-user:$DB_USER\\"}" \\
2106
2117
  "$output_file")
2107
2118
  cat "$output_file"
2108
2119
  echo "$response"
@@ -2112,6 +2123,11 @@ resource "null_resource" "create_db_user_trigger" {
2112
2123
  fi
2113
2124
  rm -f "$output_file"
2114
2125
  EOT
2126
+ environment = {
2127
+ AWS_REGION = data.aws_region.current.region
2128
+ FUNCTION_NAME = self.triggers.function_name
2129
+ DB_USER = self.triggers.db_user
2130
+ }
2115
2131
  }
2116
2132
 
2117
2133
  depends_on = [aws_lambda_function.create_db_user, module.aurora]
@@ -2174,8 +2190,8 @@ resource "null_resource" "migration_trigger" {
2174
2190
  command = <<-EOT
2175
2191
  output_file=$(mktemp)
2176
2192
  response=$(aws lambda invoke \\
2177
- --region \${data.aws_region.current.region} \\
2178
- --function-name \${self.triggers.function_name} \\
2193
+ --region "$AWS_REGION" \\
2194
+ --function-name "$FUNCTION_NAME" \\
2179
2195
  --cli-binary-format raw-in-base64-out \\
2180
2196
  "$output_file")
2181
2197
  cat "$output_file"
@@ -2186,6 +2202,10 @@ resource "null_resource" "migration_trigger" {
2186
2202
  fi
2187
2203
  rm -f "$output_file"
2188
2204
  EOT
2205
+ environment = {
2206
+ AWS_REGION = data.aws_region.current.region
2207
+ FUNCTION_NAME = self.triggers.function_name
2208
+ }
2189
2209
  }
2190
2210
 
2191
2211
  depends_on = [
@@ -2797,9 +2817,9 @@ resource "null_resource" "proxy_target_ready" {
2797
2817
  deadline=$((start_time + 600))
2798
2818
  while true; do
2799
2819
  target_state=$(aws rds describe-db-proxy-targets \\
2800
- --region \${data.aws_region.current.region} \\
2801
- --db-proxy-name \${self.triggers.db_proxy_name} \\
2802
- --target-group-name \${self.triggers.target_group_name} \\
2820
+ --region "$AWS_REGION" \\
2821
+ --db-proxy-name "$DB_PROXY_NAME" \\
2822
+ --target-group-name "$TARGET_GROUP_NAME" \\
2803
2823
  --query "Targets[?Type=='RDS_INSTANCE'] | [0].TargetHealth.State" \\
2804
2824
  --output text)
2805
2825
 
@@ -2809,13 +2829,19 @@ resource "null_resource" "proxy_target_ready" {
2809
2829
 
2810
2830
  current_time=$(date +%s)
2811
2831
  if [ "$current_time" -ge "$deadline" ]; then
2812
- echo "RDS Proxy target \${self.triggers.db_cluster_identifier} did not become AVAILABLE within 10 minutes. Last state: $target_state"
2832
+ echo "RDS Proxy target $DB_CLUSTER_IDENTIFIER did not become AVAILABLE within 10 minutes. Last state: $target_state"
2813
2833
  exit 1
2814
2834
  fi
2815
2835
 
2816
2836
  sleep 10
2817
2837
  done
2818
2838
  EOT
2839
+ environment = {
2840
+ AWS_REGION = data.aws_region.current.region
2841
+ DB_PROXY_NAME = self.triggers.db_proxy_name
2842
+ TARGET_GROUP_NAME = self.triggers.target_group_name
2843
+ DB_CLUSTER_IDENTIFIER = self.triggers.db_cluster_identifier
2844
+ }
2819
2845
  }
2820
2846
 
2821
2847
  depends_on = [
@@ -3299,10 +3325,15 @@ resource "null_resource" "docker_publish" {
3299
3325
 
3300
3326
  provisioner "local-exec" {
3301
3327
  command = <<-EOT
3302
- aws ecr get-login-password --region \${data.aws_region.current.region} | docker login --username AWS --password-stdin \${self.triggers.repository_url}
3303
- docker tag \${self.triggers.docker_image_tag} \${self.triggers.repository_url}:latest
3304
- docker push \${self.triggers.repository_url}:latest
3328
+ aws ecr get-login-password --region "$AWS_REGION" | docker login --username AWS --password-stdin "$REPOSITORY_URL"
3329
+ docker tag "$DOCKER_IMAGE_TAG" "$REPOSITORY_URL:latest"
3330
+ docker push "$REPOSITORY_URL:latest"
3305
3331
  EOT
3332
+ environment = {
3333
+ AWS_REGION = data.aws_region.current.region
3334
+ REPOSITORY_URL = self.triggers.repository_url
3335
+ DOCKER_IMAGE_TAG = self.triggers.docker_image_tag
3336
+ }
3306
3337
  }
3307
3338
 
3308
3339
  depends_on = [aws_ecr_repository_policy.migration_handler]
@@ -3565,10 +3596,10 @@ resource "null_resource" "create_db_user_trigger" {
3565
3596
  command = <<-EOT
3566
3597
  output_file=$(mktemp)
3567
3598
  response=$(aws lambda invoke \\
3568
- --region \${data.aws_region.current.region} \\
3569
- --function-name \${self.triggers.function_name} \\
3599
+ --region "$AWS_REGION" \\
3600
+ --function-name "$FUNCTION_NAME" \\
3570
3601
  --cli-binary-format raw-in-base64-out \\
3571
- --payload '{"RequestType":"Create","PhysicalResourceId":"db-user:\${self.triggers.db_user}"}' \\
3602
+ --payload "{\\"RequestType\\":\\"Create\\",\\"PhysicalResourceId\\":\\"db-user:$DB_USER\\"}" \\
3572
3603
  "$output_file")
3573
3604
  cat "$output_file"
3574
3605
  echo "$response"
@@ -3578,6 +3609,11 @@ resource "null_resource" "create_db_user_trigger" {
3578
3609
  fi
3579
3610
  rm -f "$output_file"
3580
3611
  EOT
3612
+ environment = {
3613
+ AWS_REGION = data.aws_region.current.region
3614
+ FUNCTION_NAME = self.triggers.function_name
3615
+ DB_USER = self.triggers.db_user
3616
+ }
3581
3617
  }
3582
3618
 
3583
3619
  depends_on = [aws_lambda_function.create_db_user, module.aurora]
@@ -3636,8 +3672,8 @@ resource "null_resource" "migration_trigger" {
3636
3672
  command = <<-EOT
3637
3673
  output_file=$(mktemp)
3638
3674
  response=$(aws lambda invoke \\
3639
- --region \${data.aws_region.current.region} \\
3640
- --function-name \${self.triggers.function_name} \\
3675
+ --region "$AWS_REGION" \\
3676
+ --function-name "$FUNCTION_NAME" \\
3641
3677
  --cli-binary-format raw-in-base64-out \\
3642
3678
  "$output_file")
3643
3679
  cat "$output_file"
@@ -3648,6 +3684,10 @@ resource "null_resource" "migration_trigger" {
3648
3684
  fi
3649
3685
  rm -f "$output_file"
3650
3686
  EOT
3687
+ environment = {
3688
+ AWS_REGION = data.aws_region.current.region
3689
+ FUNCTION_NAME = self.triggers.function_name
3690
+ }
3651
3691
  }
3652
3692
 
3653
3693
  depends_on = [
@@ -690,7 +690,7 @@ resource "null_resource" "upload_website_files" {
690
690
 
691
691
  provisioner "local-exec" {
692
692
  command = <<-EOT
693
- cd "\${path.root}"
693
+ cd "$ROOT_PATH"
694
694
  uv run --with boto3 python3 -c "
695
695
  import os
696
696
  import sys
@@ -779,9 +779,14 @@ def sync_to_s3(local_path, bucket_name):
779
779
  sys.exit(1)
780
780
 
781
781
  # Execute sync
782
- sync_to_s3('\${var.website_file_path}', '\${aws_s3_bucket.website.bucket}')
782
+ sync_to_s3(os.environ['WEBSITE_FILE_PATH'], os.environ['BUCKET_NAME'])
783
783
  "
784
784
  EOT
785
+ environment = {
786
+ ROOT_PATH = path.root
787
+ WEBSITE_FILE_PATH = var.website_file_path
788
+ BUCKET_NAME = aws_s3_bucket.website.bucket
789
+ }
785
790
  }
786
791
 
787
792
  depends_on = [aws_s3_bucket_policy.website_cloudfront_policy]
@@ -811,6 +816,7 @@ resource "null_resource" "cloudfront_invalidation" {
811
816
  command = <<-EOT
812
817
  uv run --with boto3 python3 -c "
813
818
  import boto3
819
+ import os
814
820
  import sys
815
821
  from botocore.exceptions import ClientError, NoCredentialsError
816
822
 
@@ -832,7 +838,7 @@ def create_invalidation(distribution_id):
832
838
 
833
839
  invalidation_id = response['Invalidation']['Id']
834
840
  print(f'CloudFront cache invalidation created: {invalidation_id}')
835
- print(f'Distribution: \${aws_cloudfront_distribution.website.id}')
841
+ print(f'Distribution: {distribution_id}')
836
842
  print(f'Status: {response[\\"Invalidation\\"][\\"Status\\"]}')
837
843
 
838
844
  except NoCredentialsError:
@@ -846,9 +852,12 @@ def create_invalidation(distribution_id):
846
852
  sys.exit(1)
847
853
 
848
854
  # Execute invalidation
849
- create_invalidation('\${aws_cloudfront_distribution.website.id}')
855
+ create_invalidation(os.environ['DISTRIBUTION_ID'])
850
856
  "
851
857
  EOT
858
+ environment = {
859
+ DISTRIBUTION_ID = aws_cloudfront_distribution.website.id
860
+ }
852
861
  }
853
862
 
854
863
  depends_on = [
@@ -65,12 +65,13 @@ resource "null_resource" "add_callback_url" {
65
65
  command = <<-EOT
66
66
  uv run --with boto3 python -c "
67
67
  import boto3
68
+ import os
68
69
  import sys
69
70
 
70
71
  # Configuration
71
- user_pool_id = '\${local.user_pool_id}'
72
- client_id = '\${local.user_pool_client_id}'
73
- new_callback_url = '\${var.callback_url}'
72
+ user_pool_id = os.environ['USER_POOL_ID']
73
+ client_id = os.environ['CLIENT_ID']
74
+ new_callback_url = os.environ['NEW_CALLBACK_URL']
74
75
 
75
76
  # Initialize Cognito client
76
77
  cognito = boto3.client('cognito-idp')
@@ -122,6 +123,11 @@ except Exception as e:
122
123
  sys.exit(1)
123
124
  "
124
125
  EOT
126
+ environment = {
127
+ USER_POOL_ID = local.user_pool_id
128
+ CLIENT_ID = local.user_pool_client_id
129
+ NEW_CALLBACK_URL = var.callback_url
130
+ }
125
131
  }
126
132
 
127
133
  depends_on = [terraform_data.validate_cognito_props]
@@ -17,34 +17,46 @@ export declare function getPythonAgentConnectionModuleName(tree: Tree): string;
17
17
  */
18
18
  export declare function getPythonAgentConnectionPackageName(tree: Tree): string;
19
19
  /**
20
- * Directories (relative to this file) holding per-protocol core client
21
- * template files. Per-connection generators select which set to emit so
22
- * the MCP connection doesn't pull in the A2A client (or vice versa).
20
+ * The connection protocols an agent framework can connect over. Each maps to a
21
+ * framework-agnostic Layer-0/1 template directory plus a per-framework Layer-2
22
+ * client directory (see `FRAMEWORKS`).
23
23
  */
24
- export declare const TS_CORE_TEMPLATES: {
25
- readonly mcp: "core-mcp";
26
- readonly a2a: "core-a2a";
27
- readonly gateway: "core-gateway";
28
- };
29
- export declare const PY_CORE_TEMPLATES: {
30
- readonly mcp: "py-core-mcp";
31
- readonly a2a: "py-core-a2a";
32
- readonly gateway: "py-core-gateway";
33
- /** Shared SigV4 `httpx.Auth` used by both MCP and A2A clients. */
34
- readonly auth: "py-core-auth";
35
- };
24
+ export type ConnectionProtocol = 'mcp' | 'gateway' | 'a2a';
25
+ /**
26
+ * The agent frameworks we can generate connection clients for. Adding a new
27
+ * framework is an additive change: append an entry to `FRAMEWORKS` with its
28
+ * Layer-2 template directories and dependencies — the framework-agnostic
29
+ * Layer-0/1 (`core-auth`, `core-shared`, the per-protocol transports/configs)
30
+ * is reused unchanged.
31
+ */
32
+ export type AgentFramework = 'strands';
36
33
  /**
37
34
  * Ensure the shared TypeScript agent-connection project exists and has the
38
- * shared core helpers (runtime-config loader). Per-connection generators
39
- * are responsible for emitting their own per-protocol core client templates.
35
+ * framework-agnostic core helpers (runtime-config loader, session context).
36
+ * Per-connection generators emit their own protocol + framework client
37
+ * templates via `addTypeScriptCoreClient`.
40
38
  */
41
39
  export declare function ensureTypeScriptAgentConnectionProject(tree: Tree): Promise<void>;
42
40
  /**
43
- * Emit one of the TypeScript core client templates (mcp or a2a) into the
44
- * agent-connection project's `src/core/` directory. Safe to call multiple
45
- * times `KeepExisting` preserves customised files.
41
+ * Emit a framework's base Layer-2 helpers (model-error logging + per-session
42
+ * agent cache) into the agent-connection project and re-export them. The agent
43
+ * server entry point imports these regardless of whether any connection client
44
+ * is wired in, so the agent generator calls this directly; connection
45
+ * generators call it transitively via `addTypeScriptCoreClient`.
46
+ */
47
+ export declare function addTypeScriptFrameworkBase(tree: Tree, framework?: AgentFramework): Promise<void>;
48
+ /**
49
+ * Emit the TypeScript client templates for a connection protocol and agent
50
+ * framework into the agent-connection project's `src/core/` directory. Safe to
51
+ * call multiple times — `KeepExisting` preserves customised files.
52
+ *
53
+ * Layers emitted:
54
+ * - Layer 0 `core-auth` (signed fetch + endpoint resolution) — always
55
+ * - Layer 1 `core-shared` MCP transport — for mcp/gateway protocols
56
+ * - Layer 1 the protocol's transport/client-config — always
57
+ * - Layer 2 the framework's base helpers + protocol client — per framework
46
58
  */
47
- export declare function addTypeScriptCoreClient(tree: Tree, kind: keyof typeof TS_CORE_TEMPLATES): void;
59
+ export declare function addTypeScriptCoreClient(tree: Tree, protocol: ConnectionProtocol, framework?: AgentFramework): Promise<void>;
48
60
  /**
49
61
  * Ensure the shared Python agent-connection project exists.
50
62
  * Only creates the project shell — per-connection generators are responsible
@@ -52,10 +64,24 @@ export declare function addTypeScriptCoreClient(tree: Tree, kind: keyof typeof T
52
64
  */
53
65
  export declare function ensurePythonAgentConnectionProject(tree: Tree): Promise<void>;
54
66
  /**
55
- * Emit a Python core client template (mcp / a2a / shared auth) into the
56
- * agent-connection project's core directory.
67
+ * Emit a framework's base Layer-2 helpers (model-error logging + per-session
68
+ * agent cache) into the Python agent-connection project and re-export them.
69
+ * The agent server entry point imports these regardless of whether a connection
70
+ * client is wired in, so the agent generator calls this directly; connection
71
+ * generators call it transitively via `addPythonCoreClient`.
72
+ */
73
+ export declare function addPythonFrameworkBase(tree: Tree, framework?: AgentFramework): Promise<void>;
74
+ /**
75
+ * Emit the Python client templates for a connection protocol and agent
76
+ * framework into the agent-connection project's core directory.
77
+ *
78
+ * Layers emitted:
79
+ * - Layer 0 `py-core-auth` (SigV4 httpx.Auth, session auth, endpoints) — always
80
+ * - Layer 1 `py-core-shared` MCP transport — for mcp/gateway protocols
81
+ * - Layer 1 the protocol's transport/client-config — always
82
+ * - Layer 2 the framework's base helpers + protocol client — per framework
57
83
  */
58
- export declare function addPythonCoreClient(tree: Tree, kind: keyof typeof PY_CORE_TEMPLATES): void;
84
+ export declare function addPythonCoreClient(tree: Tree, protocol: ConnectionProtocol, framework?: AgentFramework): Promise<void>;
59
85
  /**
60
86
  * Patch a TypeScript agent.ts to create a connection client and register it
61
87
  * in the Agent's tools. Used by the MCP and gateway connection generators —
@@ -1,12 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PY_CORE_TEMPLATES = exports.TS_CORE_TEMPLATES = exports.AGENT_CONNECTION_PROJECT_DIR = void 0;
3
+ exports.AGENT_CONNECTION_PROJECT_DIR = void 0;
4
4
  exports.getPythonAgentConnectionProjectDir = getPythonAgentConnectionProjectDir;
5
5
  exports.getPythonAgentConnectionModuleName = getPythonAgentConnectionModuleName;
6
6
  exports.getPythonAgentConnectionPackageName = getPythonAgentConnectionPackageName;
7
7
  exports.ensureTypeScriptAgentConnectionProject = ensureTypeScriptAgentConnectionProject;
8
+ exports.addTypeScriptFrameworkBase = addTypeScriptFrameworkBase;
8
9
  exports.addTypeScriptCoreClient = addTypeScriptCoreClient;
9
10
  exports.ensurePythonAgentConnectionProject = ensurePythonAgentConnectionProject;
11
+ exports.addPythonFrameworkBase = addPythonFrameworkBase;
10
12
  exports.addPythonCoreClient = addPythonCoreClient;
11
13
  exports.addTypeScriptClientToAgent = addTypeScriptClientToAgent;
12
14
  exports.addPythonClientToAgent = addPythonClientToAgent;
@@ -59,26 +61,63 @@ function getPythonAgentConnectionPackageName(tree) {
59
61
  return fullyQualifiedName;
60
62
  }
61
63
  /**
62
- * Directories (relative to this file) holding per-protocol core client
63
- * template files. Per-connection generators select which set to emit so
64
- * the MCP connection doesn't pull in the A2A client (or vice versa).
64
+ * Framework-agnostic Layer-1 templates, keyed by protocol. These resolve the
65
+ * endpoint and build the signed transport/client-config; they contain no
66
+ * framework dependency.
65
67
  */
66
- exports.TS_CORE_TEMPLATES = {
68
+ const TS_PROTOCOL_TEMPLATES = {
67
69
  mcp: 'core-mcp',
68
- a2a: 'core-a2a',
69
70
  gateway: 'core-gateway',
71
+ a2a: 'core-a2a',
70
72
  };
71
- exports.PY_CORE_TEMPLATES = {
73
+ const PY_PROTOCOL_TEMPLATES = {
72
74
  mcp: 'py-core-mcp',
73
- a2a: 'py-core-a2a',
74
75
  gateway: 'py-core-gateway',
75
- /** Shared SigV4 `httpx.Auth` used by both MCP and A2A clients. */
76
- auth: 'py-core-auth',
76
+ a2a: 'py-core-a2a',
77
+ };
78
+ const FRAMEWORKS = {
79
+ strands: {
80
+ ts: {
81
+ base: 'core-strands/base',
82
+ protocols: {
83
+ mcp: 'core-strands/mcp',
84
+ gateway: 'core-strands/gateway',
85
+ a2a: 'core-strands/a2a',
86
+ },
87
+ deps: [],
88
+ },
89
+ py: {
90
+ base: 'py-core-strands/base',
91
+ protocols: {
92
+ mcp: 'py-core-strands/mcp',
93
+ gateway: 'py-core-strands/gateway',
94
+ a2a: 'py-core-strands/a2a',
95
+ },
96
+ deps: ['strands-agents'],
97
+ },
98
+ },
77
99
  };
100
+ /** Resolve a framework's templates for a language + protocol, or throw. */
101
+ function frameworkLanguage(framework, language, protocol) {
102
+ const lang = FRAMEWORKS[framework][language];
103
+ if (!lang) {
104
+ throw new Error(`The '${framework}' framework does not support ${language === 'ts' ? 'TypeScript' : 'Python'} agents.`);
105
+ }
106
+ const protocolDir = lang.protocols[protocol];
107
+ if (!protocolDir) {
108
+ throw new Error(`The '${framework}' framework does not support ${protocol} connections for ${language === 'ts' ? 'TypeScript' : 'Python'} agents.`);
109
+ }
110
+ return { ...lang, protocol: protocolDir };
111
+ }
112
+ /** Protocols whose Layer-1 needs the shared MCP transport (`core-shared`). */
113
+ const MCP_TRANSPORT_PROTOCOLS = ['mcp', 'gateway'];
114
+ const tsCoreDir = () => (0, devkit_1.joinPathFragments)(exports.AGENT_CONNECTION_PROJECT_DIR, 'src', 'core');
115
+ const emitTs = (tree, templateDir) => (0, devkit_1.generateFiles)(tree, (0, devkit_1.joinPathFragments)(__dirname, 'files', templateDir), tsCoreDir(), {}, { overwriteStrategy: devkit_1.OverwriteStrategy.KeepExisting });
78
116
  /**
79
117
  * Ensure the shared TypeScript agent-connection project exists and has the
80
- * shared core helpers (runtime-config loader). Per-connection generators
81
- * are responsible for emitting their own per-protocol core client templates.
118
+ * framework-agnostic core helpers (runtime-config loader, session context).
119
+ * Per-connection generators emit their own protocol + framework client
120
+ * templates via `addTypeScriptCoreClient`.
82
121
  */
83
122
  async function ensureTypeScriptAgentConnectionProject(tree) {
84
123
  const projectJsonPath = (0, devkit_1.joinPathFragments)(exports.AGENT_CONNECTION_PROJECT_DIR, 'project.json');
@@ -88,23 +127,51 @@ async function ensureTypeScriptAgentConnectionProject(tree) {
88
127
  directory: (0, devkit_1.joinPathFragments)(PACKAGES_DIR, COMMON_DIR),
89
128
  });
90
129
  }
91
- // Shared core helpers — emitted regardless of which per-protocol core
92
- // client the caller needs, so both MCP and A2A clients can import from them.
93
- (0, devkit_1.generateFiles)(tree, (0, devkit_1.joinPathFragments)(__dirname, 'files', 'core-runtime-config'), (0, devkit_1.joinPathFragments)(exports.AGENT_CONNECTION_PROJECT_DIR, 'src', 'core'), {}, { overwriteStrategy: devkit_1.OverwriteStrategy.KeepExisting });
94
- // Re-export session-context helpers so agent server entry points
95
- // can set the current session on each inbound request without pulling in
96
- // the agent-connection internals.
130
+ // Framework-agnostic runtime-config + session-context helpers.
131
+ emitTs(tree, 'core-runtime-config');
132
+ // Re-export session-context helpers so agent server entry points can set the
133
+ // current session on each inbound request without pulling in internals.
97
134
  await (0, ast_1.addStarExport)(tree, (0, devkit_1.joinPathFragments)(exports.AGENT_CONNECTION_PROJECT_DIR, 'src', 'index.ts'), './core/session-context.js');
98
- await (0, ast_1.addStarExport)(tree, (0, devkit_1.joinPathFragments)(exports.AGENT_CONNECTION_PROJECT_DIR, 'src', 'index.ts'), './core/with-session-id.js');
99
- await (0, ast_1.addStarExport)(tree, (0, devkit_1.joinPathFragments)(exports.AGENT_CONNECTION_PROJECT_DIR, 'src', 'index.ts'), './core/model-errors.js');
100
135
  }
101
136
  /**
102
- * Emit one of the TypeScript core client templates (mcp or a2a) into the
103
- * agent-connection project's `src/core/` directory. Safe to call multiple
104
- * times `KeepExisting` preserves customised files.
137
+ * Emit a framework's base Layer-2 helpers (model-error logging + per-session
138
+ * agent cache) into the agent-connection project and re-export them. The agent
139
+ * server entry point imports these regardless of whether any connection client
140
+ * is wired in, so the agent generator calls this directly; connection
141
+ * generators call it transitively via `addTypeScriptCoreClient`.
105
142
  */
106
- function addTypeScriptCoreClient(tree, kind) {
107
- (0, devkit_1.generateFiles)(tree, (0, devkit_1.joinPathFragments)(__dirname, 'files', exports.TS_CORE_TEMPLATES[kind]), (0, devkit_1.joinPathFragments)(exports.AGENT_CONNECTION_PROJECT_DIR, 'src', 'core'), {}, { overwriteStrategy: devkit_1.OverwriteStrategy.KeepExisting });
143
+ async function addTypeScriptFrameworkBase(tree, framework = 'strands') {
144
+ const lang = FRAMEWORKS[framework].ts;
145
+ if (!lang) {
146
+ throw new Error(`The '${framework}' framework does not support TypeScript agents.`);
147
+ }
148
+ emitTs(tree, lang.base);
149
+ const indexPath = (0, devkit_1.joinPathFragments)(exports.AGENT_CONNECTION_PROJECT_DIR, 'src', 'index.ts');
150
+ await (0, ast_1.addStarExport)(tree, indexPath, './core/with-session-id-strands.js');
151
+ await (0, ast_1.addStarExport)(tree, indexPath, './core/model-errors-strands.js');
152
+ }
153
+ /**
154
+ * Emit the TypeScript client templates for a connection protocol and agent
155
+ * framework into the agent-connection project's `src/core/` directory. Safe to
156
+ * call multiple times — `KeepExisting` preserves customised files.
157
+ *
158
+ * Layers emitted:
159
+ * - Layer 0 `core-auth` (signed fetch + endpoint resolution) — always
160
+ * - Layer 1 `core-shared` MCP transport — for mcp/gateway protocols
161
+ * - Layer 1 the protocol's transport/client-config — always
162
+ * - Layer 2 the framework's base helpers + protocol client — per framework
163
+ */
164
+ async function addTypeScriptCoreClient(tree, protocol, framework = 'strands') {
165
+ const fw = frameworkLanguage(framework, 'ts', protocol);
166
+ emitTs(tree, 'core-auth');
167
+ if (MCP_TRANSPORT_PROTOCOLS.includes(protocol)) {
168
+ emitTs(tree, 'core-shared');
169
+ }
170
+ emitTs(tree, TS_PROTOCOL_TEMPLATES[protocol]);
171
+ // Framework Layer 2: base helpers (re-exported for the agent server) + the
172
+ // thin protocol client.
173
+ await addTypeScriptFrameworkBase(tree, framework);
174
+ emitTs(tree, fw.protocol);
108
175
  }
109
176
  /**
110
177
  * Ensure the shared Python agent-connection project exists.
@@ -134,33 +201,58 @@ async function ensurePythonAgentConnectionProject(tree) {
134
201
  if (!tree.exists(appInitPath)) {
135
202
  tree.write(appInitPath, '');
136
203
  }
137
- // Shared core helpers — emitted regardless of which per-protocol core
138
- // client the caller needs, so both MCP and A2A clients can import them.
204
+ // Framework-agnostic runtime-config + session-context helpers.
139
205
  (0, devkit_1.generateFiles)(tree, (0, devkit_1.joinPathFragments)(__dirname, 'files', 'py-core-runtime-config'), coreDir, {}, { overwriteStrategy: devkit_1.OverwriteStrategy.KeepExisting });
140
- // Re-export session-context helpers so agent server entry points
141
- // can set the current session on each inbound request without importing
142
- // the agent-connection internals directly.
206
+ // Re-export the session id context so agent server entry points can set the
207
+ // current session on each inbound request without importing internals.
143
208
  const moduleInitPath = (0, devkit_1.joinPathFragments)(moduleDir, '__init__.py');
144
209
  await addPythonReExport(tree, moduleInitPath, '.core.session_context', 'get_current_session_id');
145
210
  await addPythonReExport(tree, moduleInitPath, '.core.session_context', 'session_id_context');
146
- await addPythonReExport(tree, moduleInitPath, '.core.with_session_id', 'with_session_id');
147
- await addPythonReExport(tree, moduleInitPath, '.core.model_errors', 'log_model_errors');
148
- // Shared core helpers depend on aws-lambda-powertools for AppConfig access
149
- // and strands-agents for the model error-logging hook.
150
- (0, py_1.addDependenciesToPyProjectToml)(tree, projectDir, [
151
- 'aws-lambda-powertools',
152
- 'strands-agents',
153
- ]);
211
+ // The runtime-config loader reads AppConfig via aws-lambda-powertools.
212
+ (0, py_1.addDependenciesToPyProjectToml)(tree, projectDir, ['aws-lambda-powertools']);
154
213
  }
214
+ const pyCoreDir = (tree) => (0, devkit_1.joinPathFragments)(getPythonAgentConnectionProjectDir(tree), getPythonAgentConnectionModuleName(tree), 'core');
215
+ const emitPy = (tree, templateDir) => (0, devkit_1.generateFiles)(tree, (0, devkit_1.joinPathFragments)(__dirname, 'files', templateDir), pyCoreDir(tree), {}, { overwriteStrategy: devkit_1.OverwriteStrategy.KeepExisting });
155
216
  /**
156
- * Emit a Python core client template (mcp / a2a / shared auth) into the
157
- * agent-connection project's core directory.
217
+ * Emit a framework's base Layer-2 helpers (model-error logging + per-session
218
+ * agent cache) into the Python agent-connection project and re-export them.
219
+ * The agent server entry point imports these regardless of whether a connection
220
+ * client is wired in, so the agent generator calls this directly; connection
221
+ * generators call it transitively via `addPythonCoreClient`.
158
222
  */
159
- function addPythonCoreClient(tree, kind) {
160
- const projectDir = getPythonAgentConnectionProjectDir(tree);
161
- const moduleName = getPythonAgentConnectionModuleName(tree);
162
- const coreDir = (0, devkit_1.joinPathFragments)(projectDir, moduleName, 'core');
163
- (0, devkit_1.generateFiles)(tree, (0, devkit_1.joinPathFragments)(__dirname, 'files', exports.PY_CORE_TEMPLATES[kind]), coreDir, {}, { overwriteStrategy: devkit_1.OverwriteStrategy.KeepExisting });
223
+ async function addPythonFrameworkBase(tree, framework = 'strands') {
224
+ const lang = FRAMEWORKS[framework].py;
225
+ if (!lang) {
226
+ throw new Error(`The '${framework}' framework does not support Python agents.`);
227
+ }
228
+ emitPy(tree, lang.base);
229
+ const moduleInitPath = (0, devkit_1.joinPathFragments)(getPythonAgentConnectionProjectDir(tree), getPythonAgentConnectionModuleName(tree), '__init__.py');
230
+ await addPythonReExport(tree, moduleInitPath, '.core.with_session_id_strands', 'with_session_id');
231
+ await addPythonReExport(tree, moduleInitPath, '.core.model_errors_strands', 'log_model_errors');
232
+ if (lang.deps.length > 0) {
233
+ (0, py_1.addDependenciesToPyProjectToml)(tree, getPythonAgentConnectionProjectDir(tree), lang.deps);
234
+ }
235
+ }
236
+ /**
237
+ * Emit the Python client templates for a connection protocol and agent
238
+ * framework into the agent-connection project's core directory.
239
+ *
240
+ * Layers emitted:
241
+ * - Layer 0 `py-core-auth` (SigV4 httpx.Auth, session auth, endpoints) — always
242
+ * - Layer 1 `py-core-shared` MCP transport — for mcp/gateway protocols
243
+ * - Layer 1 the protocol's transport/client-config — always
244
+ * - Layer 2 the framework's base helpers + protocol client — per framework
245
+ */
246
+ async function addPythonCoreClient(tree, protocol, framework = 'strands') {
247
+ const fw = frameworkLanguage(framework, 'py', protocol);
248
+ emitPy(tree, 'py-core-auth');
249
+ if (MCP_TRANSPORT_PROTOCOLS.includes(protocol)) {
250
+ emitPy(tree, 'py-core-shared');
251
+ }
252
+ emitPy(tree, PY_PROTOCOL_TEMPLATES[protocol]);
253
+ // Framework Layer 2: base helpers + the thin protocol client.
254
+ await addPythonFrameworkBase(tree, framework);
255
+ emitPy(tree, fw.protocol);
164
256
  }
165
257
  /**
166
258
  * Patch a TypeScript agent.ts to create a connection client and register it