@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.
- package/generators.json +9 -1
- package/package.json +1 -1
- package/src/agentcore-gateway/attach-upstream.d.ts +33 -0
- package/src/agentcore-gateway/attach-upstream.js +41 -0
- package/src/agentcore-gateway/attach-upstream.js.map +1 -0
- package/src/agentcore-gateway/files/project/serve-local.ts.template +3 -2
- package/src/agentcore-gateway/gateway-connection/generator.d.ts +21 -0
- package/src/agentcore-gateway/gateway-connection/generator.js +102 -0
- package/src/agentcore-gateway/gateway-connection/generator.js.map +1 -0
- package/src/agentcore-gateway/gateway-connection/schema.d.ts +12 -0
- package/src/agentcore-gateway/gateway-connection/schema.json +26 -0
- package/src/agentcore-gateway/mcp-connection/generator.js +8 -24
- package/src/agentcore-gateway/mcp-connection/generator.js.map +1 -1
- package/src/connection/generator.js +66 -63
- package/src/connection/generator.js.map +1 -1
- package/src/license/generator.js +8 -19
- package/src/license/generator.js.map +1 -1
- package/src/license/known-exceptions.d.ts +0 -1
- package/src/license/known-exceptions.js +1 -8
- package/src/license/known-exceptions.js.map +1 -1
- package/src/py/agent/__snapshots__/generator.spec.ts.snap +15 -6
- package/src/py/agent/a2a-connection/__snapshots__/generator.spec.ts.snap +201 -0
- package/src/py/agent/a2a-connection/files/agent-connection/app/{__targetAgentSnakeCase___client.py.template → __targetAgentSnakeCase___client_strands.py.template} +7 -5
- package/src/py/agent/a2a-connection/generator.js +6 -5
- package/src/py/agent/a2a-connection/generator.js.map +1 -1
- package/src/py/agent/files/http/main.py.template +2 -2
- package/src/py/agent/gateway-connection/__snapshots__/generator.spec.ts.snap +197 -0
- package/src/py/agent/gateway-connection/files/agent-connection/app/{__gatewaySnakeCase___client.py.template → __gatewaySnakeCase___client_strands.py.template} +6 -6
- package/src/py/agent/gateway-connection/generator.js +5 -5
- package/src/py/agent/gateway-connection/generator.js.map +1 -1
- package/src/py/agent/generator.js +3 -5
- package/src/py/agent/generator.js.map +1 -1
- package/src/py/agent/mcp-connection/__snapshots__/generator.spec.ts.snap +157 -79
- package/src/py/agent/mcp-connection/files/agent-connection/app/{__mcpServerSnakeCase___client.py.template → __mcpServerSnakeCase___client_strands.py.template} +7 -5
- package/src/py/agent/mcp-connection/generator.js +5 -5
- package/src/py/agent/mcp-connection/generator.js.map +1 -1
- package/src/py/fast-api/__snapshots__/generator.spec.ts.snap +37 -3
- package/src/py/fast-api/files/app/__name__/main.py.template +4 -1
- package/src/py/mcp-server/__snapshots__/generator.spec.ts.snap +13 -4
- package/src/smithy/project/__snapshots__/generator.spec.ts.snap +1 -0
- package/src/smithy/project/files/src/operations/echo.smithy.template +1 -0
- package/src/terraform/project/files/application/src/main.tf.template +6 -1
- package/src/trpc/backend/__snapshots__/generator.spec.ts.snap +35 -4
- package/src/trpc/backend/files/src/procedures/echo.ts.template +1 -1
- package/src/trpc/backend/files/src/schema/echo.ts.template +2 -2
- package/src/ts/agent/__snapshots__/generator.spec.ts.snap +14 -5
- package/src/ts/agent/a2a-connection/__snapshots__/generator.spec.ts.snap +256 -0
- package/src/ts/agent/a2a-connection/files/agent-connection/app/{__targetAgentKebabCase__-client.ts.template → __targetAgentKebabCase__-client-strands.ts.template} +5 -5
- package/src/ts/agent/a2a-connection/generator.js +3 -3
- package/src/ts/agent/a2a-connection/generator.js.map +1 -1
- package/src/ts/agent/files/http/router.ts.template +1 -1
- package/src/ts/agent/gateway-connection/__snapshots__/generator.spec.ts.snap +220 -0
- package/src/ts/agent/gateway-connection/files/agent-connection/app/{__gatewayKebabCase__-client.ts.template → __gatewayKebabCase__-client-strands.ts.template} +5 -5
- package/src/ts/agent/gateway-connection/generator.js +3 -3
- package/src/ts/agent/gateway-connection/generator.js.map +1 -1
- package/src/ts/agent/generator.js +3 -0
- package/src/ts/agent/generator.js.map +1 -1
- package/src/ts/agent/mcp-connection/__snapshots__/generator.spec.ts.snap +183 -110
- package/src/ts/agent/mcp-connection/files/agent-connection/app/{__mcpServerKebabCase__-client.ts.template → __mcpServerKebabCase__-client-strands.ts.template} +5 -5
- package/src/ts/agent/mcp-connection/generator.js +3 -3
- package/src/ts/agent/mcp-connection/generator.js.map +1 -1
- package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +13 -4
- package/src/ts/rdb/__snapshots__/generator.spec.ts.snap +64 -24
- package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +13 -4
- package/src/ts/react-website/cognito-auth/__snapshots__/generator.terraform.spec.ts.snap +9 -3
- package/src/utils/agent-connection/agent-connection.d.ts +50 -24
- package/src/utils/agent-connection/agent-connection.js +137 -45
- package/src/utils/agent-connection/agent-connection.js.map +1 -1
- package/src/utils/agent-connection/files/core-a2a/agentcore-a2a-client-config.ts.template +93 -0
- package/src/utils/agent-connection/files/core-auth/agentcore-endpoints.ts.template +37 -0
- package/src/utils/agent-connection/files/core-auth/agentcore-fetch.ts.template +54 -0
- package/src/utils/agent-connection/files/core-gateway/agentcore-gateway-mcp-transport.ts.template +41 -0
- package/src/utils/agent-connection/files/core-mcp/agentcore-mcp-transport.ts.template +70 -0
- package/src/utils/agent-connection/files/core-shared/agentcore-transport.ts.template +39 -0
- package/src/utils/agent-connection/files/core-strands/a2a/agentcore-a2a-client-strands.ts.template +61 -0
- package/src/utils/agent-connection/files/core-strands/gateway/agentcore-gateway-mcp-client-strands.ts.template +26 -0
- package/src/utils/agent-connection/files/core-strands/mcp/agentcore-mcp-client-strands.ts.template +27 -0
- package/src/utils/agent-connection/files/py-core-a2a/agentcore_a2a_client_config.py.template +43 -0
- package/src/utils/agent-connection/files/py-core-auth/agentcore_endpoints.py.template +47 -0
- package/src/utils/agent-connection/files/py-core-auth/auth/session.py.template +51 -0
- package/src/utils/agent-connection/files/py-core-gateway/agentcore_gateway_mcp_transport.py.template +28 -0
- package/src/utils/agent-connection/files/py-core-mcp/agentcore_mcp_transport.py.template +34 -0
- package/src/utils/agent-connection/files/py-core-shared/agentcore_transport.py.template +40 -0
- package/src/utils/agent-connection/files/py-core-strands/a2a/agentcore_a2a_client_strands.py.template +66 -0
- package/src/utils/agent-connection/files/py-core-strands/gateway/agentcore_gateway_mcp_client_strands.py.template +22 -0
- package/src/utils/agent-connection/files/py-core-strands/mcp/agentcore_mcp_client_strands.py.template +30 -0
- package/src/utils/agent-core-constructs/files/cdk/app/agentcore-gateway/__nameKebabCase__/__nameKebabCase__.ts.template +3 -0
- package/src/utils/agent-core-constructs/files/cdk/core/agentcore-gateway/agentcore-gateway.ts.template +110 -28
- package/src/utils/agent-core-constructs/files/terraform/app/agentcore-gateway/__nameKebabCase__/__nameKebabCase__.tf.template +95 -2
- package/src/utils/agent-core-constructs/files/terraform/core/agent-core/runtime.tf.template +13 -4
- package/src/utils/api-constructs/files/cdk/core/api/http/http-api.ts.template +9 -0
- package/src/utils/api-constructs/files/cdk/core/api/rest/rest-api.ts.template +23 -1
- package/src/utils/files/terraform/src/core/runtime-config/appconfig-deployment/appconfig-deployment.tf.template +9 -3
- package/src/utils/files/terraform/src/core/runtime-config/read/read.tf.template +7 -2
- package/src/utils/identity-constructs/files/terraform/core/user-identity/add-callback-url/add-callback-url.tf.template +9 -3
- package/src/utils/rdb-constructs/files/terraform/app/dbs/__nameKebabCase__/__nameKebabCase__.tf.template +22 -8
- package/src/utils/rdb-constructs/files/terraform/core/rdb/aurora/aurora.tf.template +10 -4
- package/src/utils/versions.d.ts +1 -1
- package/src/utils/versions.js +1 -1
- package/src/utils/website-constructs/files/terraform/core/static-website/static-website.tf.template +13 -4
- package/src/utils/agent-connection/files/core-a2a/agentcore-a2a-client.ts.template +0 -123
- package/src/utils/agent-connection/files/core-gateway/agentcore-gateway-mcp-client.ts.template +0 -78
- package/src/utils/agent-connection/files/core-mcp/agentcore-mcp-client.ts.template +0 -128
- package/src/utils/agent-connection/files/py-core-a2a/agentcore_a2a_client.py.template +0 -120
- package/src/utils/agent-connection/files/py-core-gateway/agentcore_gateway_mcp_client.py.template +0 -78
- package/src/utils/agent-connection/files/py-core-mcp/agentcore_mcp_client.py.template +0 -89
- /package/src/utils/agent-connection/files/{core-runtime-config/model-errors.ts.template → core-strands/base/model-errors-strands.ts.template} +0 -0
- /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
- /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
- /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
|
@@ -61,12 +61,13 @@ resource "null_resource" "add_callback_url" {
|
|
|
61
61
|
command = <<-EOT
|
|
62
62
|
uv run --with boto3 python -c "
|
|
63
63
|
import boto3
|
|
64
|
+
import os
|
|
64
65
|
import sys
|
|
65
66
|
|
|
66
67
|
# Configuration
|
|
67
|
-
user_pool_id =
|
|
68
|
-
client_id =
|
|
69
|
-
new_callback_url =
|
|
68
|
+
user_pool_id = os.environ['USER_POOL_ID']
|
|
69
|
+
client_id = os.environ['CLIENT_ID']
|
|
70
|
+
new_callback_url = os.environ['NEW_CALLBACK_URL']
|
|
70
71
|
|
|
71
72
|
# Initialize Cognito client
|
|
72
73
|
cognito = boto3.client('cognito-idp')
|
|
@@ -118,6 +119,11 @@ except Exception as e:
|
|
|
118
119
|
sys.exit(1)
|
|
119
120
|
"
|
|
120
121
|
EOT
|
|
122
|
+
environment = {
|
|
123
|
+
USER_POOL_ID = local.user_pool_id
|
|
124
|
+
CLIENT_ID = local.user_pool_client_id
|
|
125
|
+
NEW_CALLBACK_URL = var.callback_url
|
|
126
|
+
}
|
|
121
127
|
}
|
|
122
128
|
|
|
123
129
|
depends_on = [terraform_data.validate_cognito_props]
|
|
@@ -287,10 +287,15 @@ resource "null_resource" "docker_publish" {
|
|
|
287
287
|
|
|
288
288
|
provisioner "local-exec" {
|
|
289
289
|
command = <<-EOT
|
|
290
|
-
aws ecr get-login-password --region $
|
|
291
|
-
<%= containerEngine %> tag $
|
|
292
|
-
<%= containerEngine %> push $
|
|
290
|
+
aws ecr get-login-password --region "$AWS_REGION" | <%= containerEngine %> login --username AWS --password-stdin "$REPOSITORY_URL"
|
|
291
|
+
<%= containerEngine %> tag "$DOCKER_IMAGE_TAG" "$REPOSITORY_URL:latest"
|
|
292
|
+
<%= containerEngine %> push "$REPOSITORY_URL:latest"
|
|
293
293
|
EOT
|
|
294
|
+
environment = {
|
|
295
|
+
AWS_REGION = data.aws_region.current.region
|
|
296
|
+
REPOSITORY_URL = self.triggers.repository_url
|
|
297
|
+
DOCKER_IMAGE_TAG = self.triggers.docker_image_tag
|
|
298
|
+
}
|
|
294
299
|
}
|
|
295
300
|
|
|
296
301
|
depends_on = [aws_ecr_repository_policy.migration_handler]
|
|
@@ -574,10 +579,10 @@ resource "null_resource" "create_db_user_trigger" {
|
|
|
574
579
|
command = <<-EOT
|
|
575
580
|
output_file=$(mktemp)
|
|
576
581
|
response=$(aws lambda invoke \
|
|
577
|
-
--region $
|
|
578
|
-
--function-name $
|
|
582
|
+
--region "$AWS_REGION" \
|
|
583
|
+
--function-name "$FUNCTION_NAME" \
|
|
579
584
|
--cli-binary-format raw-in-base64-out \
|
|
580
|
-
--payload
|
|
585
|
+
--payload "{\"RequestType\":\"Create\",\"PhysicalResourceId\":\"db-user:$DB_USER\"}" \
|
|
581
586
|
"$output_file")
|
|
582
587
|
cat "$output_file"
|
|
583
588
|
echo "$response"
|
|
@@ -587,6 +592,11 @@ resource "null_resource" "create_db_user_trigger" {
|
|
|
587
592
|
fi
|
|
588
593
|
rm -f "$output_file"
|
|
589
594
|
EOT
|
|
595
|
+
environment = {
|
|
596
|
+
AWS_REGION = data.aws_region.current.region
|
|
597
|
+
FUNCTION_NAME = self.triggers.function_name
|
|
598
|
+
DB_USER = self.triggers.db_user
|
|
599
|
+
}
|
|
590
600
|
}
|
|
591
601
|
|
|
592
602
|
depends_on = [aws_lambda_function.create_db_user, module.aurora]
|
|
@@ -655,8 +665,8 @@ resource "null_resource" "migration_trigger" {
|
|
|
655
665
|
command = <<-EOT
|
|
656
666
|
output_file=$(mktemp)
|
|
657
667
|
response=$(aws lambda invoke \
|
|
658
|
-
--region $
|
|
659
|
-
--function-name $
|
|
668
|
+
--region "$AWS_REGION" \
|
|
669
|
+
--function-name "$FUNCTION_NAME" \
|
|
660
670
|
--cli-binary-format raw-in-base64-out \
|
|
661
671
|
"$output_file")
|
|
662
672
|
cat "$output_file"
|
|
@@ -667,6 +677,10 @@ resource "null_resource" "migration_trigger" {
|
|
|
667
677
|
fi
|
|
668
678
|
rm -f "$output_file"
|
|
669
679
|
EOT
|
|
680
|
+
environment = {
|
|
681
|
+
AWS_REGION = data.aws_region.current.region
|
|
682
|
+
FUNCTION_NAME = self.triggers.function_name
|
|
683
|
+
}
|
|
670
684
|
}
|
|
671
685
|
|
|
672
686
|
depends_on = [
|
|
@@ -540,9 +540,9 @@ resource "null_resource" "proxy_target_ready" {
|
|
|
540
540
|
deadline=$((start_time + 600))
|
|
541
541
|
while true; do
|
|
542
542
|
target_state=$(aws rds describe-db-proxy-targets \
|
|
543
|
-
--region $
|
|
544
|
-
--db-proxy-name $
|
|
545
|
-
--target-group-name $
|
|
543
|
+
--region "$AWS_REGION" \
|
|
544
|
+
--db-proxy-name "$DB_PROXY_NAME" \
|
|
545
|
+
--target-group-name "$TARGET_GROUP_NAME" \
|
|
546
546
|
--query "Targets[?Type=='RDS_INSTANCE'] | [0].TargetHealth.State" \
|
|
547
547
|
--output text)
|
|
548
548
|
|
|
@@ -552,13 +552,19 @@ resource "null_resource" "proxy_target_ready" {
|
|
|
552
552
|
|
|
553
553
|
current_time=$(date +%s)
|
|
554
554
|
if [ "$current_time" -ge "$deadline" ]; then
|
|
555
|
-
echo "RDS Proxy target $
|
|
555
|
+
echo "RDS Proxy target $DB_CLUSTER_IDENTIFIER did not become AVAILABLE within 10 minutes. Last state: $target_state"
|
|
556
556
|
exit 1
|
|
557
557
|
fi
|
|
558
558
|
|
|
559
559
|
sleep 10
|
|
560
560
|
done
|
|
561
561
|
EOT
|
|
562
|
+
environment = {
|
|
563
|
+
AWS_REGION = data.aws_region.current.region
|
|
564
|
+
DB_PROXY_NAME = self.triggers.db_proxy_name
|
|
565
|
+
TARGET_GROUP_NAME = self.triggers.target_group_name
|
|
566
|
+
DB_CLUSTER_IDENTIFIER = self.triggers.db_cluster_identifier
|
|
567
|
+
}
|
|
562
568
|
}
|
|
563
569
|
|
|
564
570
|
depends_on = [
|
package/src/utils/versions.d.ts
CHANGED
|
@@ -135,7 +135,7 @@ export declare const withVersions: (deps: ITsDepVersion[]) => {
|
|
|
135
135
|
*/
|
|
136
136
|
export declare const PY_VERSIONS: {
|
|
137
137
|
readonly 'ag-ui-protocol': "==0.1.19";
|
|
138
|
-
readonly 'ag-ui-strands': "==0.1
|
|
138
|
+
readonly 'ag-ui-strands': "==0.2.1";
|
|
139
139
|
readonly 'aws-lambda-powertools': "==3.29.0";
|
|
140
140
|
readonly 'aws-lambda-powertools[tracer]': "==3.29.0";
|
|
141
141
|
readonly 'aws-lambda-powertools[parser]': "==3.29.0";
|
package/src/utils/versions.js
CHANGED
|
@@ -136,7 +136,7 @@ exports.withVersions = withVersions;
|
|
|
136
136
|
*/
|
|
137
137
|
exports.PY_VERSIONS = {
|
|
138
138
|
'ag-ui-protocol': '==0.1.19',
|
|
139
|
-
'ag-ui-strands': '==0.1
|
|
139
|
+
'ag-ui-strands': '==0.2.1',
|
|
140
140
|
'aws-lambda-powertools': '==3.29.0',
|
|
141
141
|
'aws-lambda-powertools[tracer]': '==3.29.0',
|
|
142
142
|
'aws-lambda-powertools[parser]': '==3.29.0',
|
package/src/utils/website-constructs/files/terraform/core/static-website/static-website.tf.template
CHANGED
|
@@ -553,7 +553,7 @@ resource "null_resource" "upload_website_files" {
|
|
|
553
553
|
|
|
554
554
|
provisioner "local-exec" {
|
|
555
555
|
command = <<-EOT
|
|
556
|
-
cd "$
|
|
556
|
+
cd "$ROOT_PATH"
|
|
557
557
|
uv run --with boto3 python3 -c "
|
|
558
558
|
import os
|
|
559
559
|
import sys
|
|
@@ -642,9 +642,14 @@ def sync_to_s3(local_path, bucket_name):
|
|
|
642
642
|
sys.exit(1)
|
|
643
643
|
|
|
644
644
|
# Execute sync
|
|
645
|
-
sync_to_s3(
|
|
645
|
+
sync_to_s3(os.environ['WEBSITE_FILE_PATH'], os.environ['BUCKET_NAME'])
|
|
646
646
|
"
|
|
647
647
|
EOT
|
|
648
|
+
environment = {
|
|
649
|
+
ROOT_PATH = path.root
|
|
650
|
+
WEBSITE_FILE_PATH = var.website_file_path
|
|
651
|
+
BUCKET_NAME = aws_s3_bucket.website.bucket
|
|
652
|
+
}
|
|
648
653
|
}
|
|
649
654
|
|
|
650
655
|
depends_on = [aws_s3_bucket_policy.website_cloudfront_policy]
|
|
@@ -674,6 +679,7 @@ resource "null_resource" "cloudfront_invalidation" {
|
|
|
674
679
|
command = <<-EOT
|
|
675
680
|
uv run --with boto3 python3 -c "
|
|
676
681
|
import boto3
|
|
682
|
+
import os
|
|
677
683
|
import sys
|
|
678
684
|
from botocore.exceptions import ClientError, NoCredentialsError
|
|
679
685
|
|
|
@@ -695,7 +701,7 @@ def create_invalidation(distribution_id):
|
|
|
695
701
|
|
|
696
702
|
invalidation_id = response['Invalidation']['Id']
|
|
697
703
|
print(f'CloudFront cache invalidation created: {invalidation_id}')
|
|
698
|
-
print(f'Distribution:
|
|
704
|
+
print(f'Distribution: {distribution_id}')
|
|
699
705
|
print(f'Status: {response[\"Invalidation\"][\"Status\"]}')
|
|
700
706
|
|
|
701
707
|
except NoCredentialsError:
|
|
@@ -709,9 +715,12 @@ def create_invalidation(distribution_id):
|
|
|
709
715
|
sys.exit(1)
|
|
710
716
|
|
|
711
717
|
# Execute invalidation
|
|
712
|
-
create_invalidation(
|
|
718
|
+
create_invalidation(os.environ['DISTRIBUTION_ID'])
|
|
713
719
|
"
|
|
714
720
|
EOT
|
|
721
|
+
environment = {
|
|
722
|
+
DISTRIBUTION_ID = aws_cloudfront_distribution.website.id
|
|
723
|
+
}
|
|
715
724
|
}
|
|
716
725
|
|
|
717
726
|
depends_on = [
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ClientFactory,
|
|
3
|
-
ClientFactoryOptions,
|
|
4
|
-
DefaultAgentCardResolver,
|
|
5
|
-
JsonRpcTransportFactory,
|
|
6
|
-
} from '@a2a-js/sdk/client';
|
|
7
|
-
import { fromNodeProviderChain } from '@aws-sdk/credential-providers';
|
|
8
|
-
import { A2AAgent } from '@strands-agents/sdk/a2a';
|
|
9
|
-
import { AwsClient } from 'aws4fetch';
|
|
10
|
-
import { getCurrentSessionId } from './session-context.js';
|
|
11
|
-
|
|
12
|
-
const SESSION_HEADER = 'X-Amzn-Bedrock-AgentCore-Runtime-Session-Id';
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Common options for creating an AgentCore A2A client.
|
|
16
|
-
*/
|
|
17
|
-
export interface AgentCoreA2aClientOptions {
|
|
18
|
-
/** The ARN of the Bedrock AgentCore Runtime to connect to. */
|
|
19
|
-
agentRuntimeArn: string;
|
|
20
|
-
/** Optional description for the remote agent. */
|
|
21
|
-
description?: string;
|
|
22
|
-
/** Optional friendly name for the remote agent. */
|
|
23
|
-
name?: string;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/** Options for an IAM-authenticated A2A client. */
|
|
27
|
-
export interface AgentCoreA2aClientIamOptions
|
|
28
|
-
extends AgentCoreA2aClientOptions {
|
|
29
|
-
credentialProvider?: ReturnType<typeof fromNodeProviderChain>;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/** Options for a JWT-authenticated A2A client. */
|
|
33
|
-
export interface AgentCoreA2aClientJwtOptions
|
|
34
|
-
extends AgentCoreA2aClientOptions {
|
|
35
|
-
accessTokenProvider: () => Promise<string>;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/** Options for a no-auth A2A client (local dev). */
|
|
39
|
-
export interface AgentCoreA2aClientNoAuthOptions {
|
|
40
|
-
/** Full URL of the local A2A endpoint. */
|
|
41
|
-
url: string;
|
|
42
|
-
name?: string;
|
|
43
|
-
description?: string;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
interface BuildOptions {
|
|
47
|
-
name?: string;
|
|
48
|
-
description?: string;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/** Factory for A2A clients that forward the current async-context session. */
|
|
52
|
-
export class AgentCoreA2aClient {
|
|
53
|
-
/**
|
|
54
|
-
* Construct the A2A invocations URL for an AgentCore runtime ARN and
|
|
55
|
-
* extract the region. A2A on AgentCore is mounted at `/invocations/`
|
|
56
|
-
* (trailing slash matters).
|
|
57
|
-
*/
|
|
58
|
-
private static buildUrl(agentRuntimeArn: string): {
|
|
59
|
-
region: string;
|
|
60
|
-
url: string;
|
|
61
|
-
} {
|
|
62
|
-
const region = agentRuntimeArn.split(':')[3];
|
|
63
|
-
const url = `https://bedrock-agentcore.${region}.amazonaws.com/runtimes/${encodeURIComponent(agentRuntimeArn)}/invocations/`;
|
|
64
|
-
return { region, url };
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
private static build(
|
|
68
|
-
url: string,
|
|
69
|
-
authFetch: typeof fetch,
|
|
70
|
-
options: BuildOptions,
|
|
71
|
-
): A2AAgent {
|
|
72
|
-
const sessionFetch: typeof fetch = (input, init) => {
|
|
73
|
-
const headers = new Headers(init?.headers);
|
|
74
|
-
const sessionId = getCurrentSessionId();
|
|
75
|
-
if (sessionId) headers.set(SESSION_HEADER, sessionId);
|
|
76
|
-
return authFetch(input, { ...init, headers });
|
|
77
|
-
};
|
|
78
|
-
const clientFactory = new ClientFactory({
|
|
79
|
-
...ClientFactoryOptions.default,
|
|
80
|
-
transports: [new JsonRpcTransportFactory({ fetchImpl: sessionFetch })],
|
|
81
|
-
cardResolver: new DefaultAgentCardResolver({ fetchImpl: sessionFetch }),
|
|
82
|
-
});
|
|
83
|
-
return new A2AAgent({
|
|
84
|
-
url,
|
|
85
|
-
clientFactory,
|
|
86
|
-
...(options.name ? { name: options.name } : {}),
|
|
87
|
-
...(options.description ? { description: options.description } : {}),
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
static withIamAuth(options: AgentCoreA2aClientIamOptions): A2AAgent {
|
|
92
|
-
const { region, url } = AgentCoreA2aClient.buildUrl(options.agentRuntimeArn);
|
|
93
|
-
const credentialProvider =
|
|
94
|
-
options.credentialProvider ?? fromNodeProviderChain();
|
|
95
|
-
const sigv4Fetch: typeof fetch = async (...args) => {
|
|
96
|
-
const client = new AwsClient({
|
|
97
|
-
...(await credentialProvider()),
|
|
98
|
-
service: 'bedrock-agentcore',
|
|
99
|
-
region,
|
|
100
|
-
});
|
|
101
|
-
return client.fetch(...args);
|
|
102
|
-
};
|
|
103
|
-
return AgentCoreA2aClient.build(url, sigv4Fetch, options);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
static withJwtAuth(options: AgentCoreA2aClientJwtOptions): A2AAgent {
|
|
107
|
-
const { url } = AgentCoreA2aClient.buildUrl(options.agentRuntimeArn);
|
|
108
|
-
const bearerFetch: typeof fetch = async (input, init) => {
|
|
109
|
-
const headers = new Headers(init?.headers);
|
|
110
|
-
headers.set(
|
|
111
|
-
'Authorization',
|
|
112
|
-
`Bearer ${await options.accessTokenProvider()}`,
|
|
113
|
-
);
|
|
114
|
-
return fetch(input, { ...init, headers });
|
|
115
|
-
};
|
|
116
|
-
return AgentCoreA2aClient.build(url, bearerFetch, options);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/** For local dev — plain HTTP, no auth. */
|
|
120
|
-
static withoutAuth(options: AgentCoreA2aClientNoAuthOptions): A2AAgent {
|
|
121
|
-
return AgentCoreA2aClient.build(options.url, fetch, options);
|
|
122
|
-
}
|
|
123
|
-
}
|
package/src/utils/agent-connection/files/core-gateway/agentcore-gateway-mcp-client.ts.template
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { McpClient } from '@strands-agents/sdk';
|
|
2
|
-
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
3
|
-
import { AwsClient } from 'aws4fetch';
|
|
4
|
-
import { fromNodeProviderChain } from '@aws-sdk/credential-providers';
|
|
5
|
-
import { getCurrentSessionId } from './session-context.js';
|
|
6
|
-
|
|
7
|
-
const SESSION_HEADER = 'X-Amzn-Bedrock-AgentCore-Runtime-Session-Id';
|
|
8
|
-
|
|
9
|
-
export interface AgentCoreGatewayMcpClientIamOptions {
|
|
10
|
-
/**
|
|
11
|
-
* The MCP URL of the AgentCore Gateway, of the form
|
|
12
|
-
* https://<gatewayId>.gateway.bedrock-agentcore.<region>.amazonaws.com/mcp
|
|
13
|
-
*/
|
|
14
|
-
gatewayUrl: string;
|
|
15
|
-
/** AWS region override; by default parsed from `gatewayUrl`. */
|
|
16
|
-
region?: string;
|
|
17
|
-
/** AWS credential provider; defaults to the standard provider chain. */
|
|
18
|
-
credentialProvider?: ReturnType<typeof fromNodeProviderChain>;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Factory for MCP clients that connect to an AgentCore Gateway. Forwards the
|
|
23
|
-
* current async-context session via the AgentCore session header, which the
|
|
24
|
-
* gateway propagates to downstream MCP server targets.
|
|
25
|
-
*/
|
|
26
|
-
export class AgentCoreGatewayMcpClient {
|
|
27
|
-
/** Create a gateway MCP client authenticated with IAM SigV4. */
|
|
28
|
-
static withIamAuth(options: AgentCoreGatewayMcpClientIamOptions): McpClient {
|
|
29
|
-
const credentialProvider =
|
|
30
|
-
options.credentialProvider ?? fromNodeProviderChain();
|
|
31
|
-
const region =
|
|
32
|
-
options.region ?? parseRegionFromGatewayUrl(options.gatewayUrl);
|
|
33
|
-
|
|
34
|
-
const sigv4Fetch: typeof fetch = async (input, init) => {
|
|
35
|
-
const client = new AwsClient({
|
|
36
|
-
...(await credentialProvider()),
|
|
37
|
-
service: 'bedrock-agentcore',
|
|
38
|
-
region,
|
|
39
|
-
});
|
|
40
|
-
return client.fetch(input, {
|
|
41
|
-
...init,
|
|
42
|
-
headers: withSessionHeader(init?.headers),
|
|
43
|
-
});
|
|
44
|
-
};
|
|
45
|
-
return AgentCoreGatewayMcpClient.create(options.gatewayUrl, sigv4Fetch);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/** Plain-HTTP gateway client, for the local gateway started by serve-local. */
|
|
49
|
-
static withoutAuth(options: { gatewayUrl: string }): McpClient {
|
|
50
|
-
const plainFetch: typeof fetch = async (input, init) =>
|
|
51
|
-
fetch(input, { ...init, headers: withSessionHeader(init?.headers) });
|
|
52
|
-
return AgentCoreGatewayMcpClient.create(options.gatewayUrl, plainFetch);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
private static create(gatewayUrl: string, fetchFn: typeof fetch): McpClient {
|
|
56
|
-
const transport = new StreamableHTTPClientTransport(new URL(gatewayUrl), {
|
|
57
|
-
fetch: fetchFn,
|
|
58
|
-
});
|
|
59
|
-
return new McpClient({ transport });
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const withSessionHeader = (init?: RequestInit['headers']): Headers => {
|
|
64
|
-
const headers = new Headers(init);
|
|
65
|
-
const sessionId = getCurrentSessionId();
|
|
66
|
-
if (sessionId) headers.set(SESSION_HEADER, sessionId);
|
|
67
|
-
return headers;
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
const parseRegionFromGatewayUrl = (gatewayUrl: string): string => {
|
|
71
|
-
const match = /\.bedrock-agentcore\.([^.]+)\.amazonaws\.com/.exec(gatewayUrl);
|
|
72
|
-
if (!match) {
|
|
73
|
-
throw new Error(
|
|
74
|
-
`Cannot determine region from gateway URL '${gatewayUrl}'. Pass region explicitly.`,
|
|
75
|
-
);
|
|
76
|
-
}
|
|
77
|
-
return match[1];
|
|
78
|
-
};
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
import { McpClient } from '@strands-agents/sdk';
|
|
2
|
-
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
3
|
-
import { AwsClient } from 'aws4fetch';
|
|
4
|
-
import { fromNodeProviderChain } from '@aws-sdk/credential-providers';
|
|
5
|
-
import { getCurrentSessionId } from './session-context.js';
|
|
6
|
-
|
|
7
|
-
const SESSION_HEADER = 'X-Amzn-Bedrock-AgentCore-Runtime-Session-Id';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Common options for creating an AgentCore MCP client.
|
|
11
|
-
*/
|
|
12
|
-
export interface AgentCoreMcpClientOptions {
|
|
13
|
-
/**
|
|
14
|
-
* The ARN of the Bedrock AgentCore Runtime to connect to.
|
|
15
|
-
*/
|
|
16
|
-
agentRuntimeArn: string;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Options for creating an AgentCore MCP client with IAM authentication.
|
|
21
|
-
*/
|
|
22
|
-
export interface AgentCoreMcpClientIamOptions
|
|
23
|
-
extends AgentCoreMcpClientOptions {
|
|
24
|
-
/**
|
|
25
|
-
* Optional AWS credential provider. If not provided, uses the default
|
|
26
|
-
* credential provider chain from the AWS SDK.
|
|
27
|
-
*/
|
|
28
|
-
credentialProvider?: ReturnType<typeof fromNodeProviderChain>;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Options for creating an AgentCore MCP client with JWT authentication.
|
|
33
|
-
*/
|
|
34
|
-
export interface AgentCoreMcpClientJwtOptions
|
|
35
|
-
extends AgentCoreMcpClientOptions {
|
|
36
|
-
/**
|
|
37
|
-
* A function which returns the JWT access token used to authenticate.
|
|
38
|
-
*/
|
|
39
|
-
accessTokenProvider: () => Promise<string>;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Options for creating an MCP client with no auth (local dev).
|
|
44
|
-
*/
|
|
45
|
-
export interface AgentCoreMcpClientNoAuthOptions {
|
|
46
|
-
/** Full URL of the local MCP endpoint. */
|
|
47
|
-
url: string;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
interface CreateOptions {
|
|
51
|
-
url: string;
|
|
52
|
-
buildHeaders?: () => Promise<Record<string, string>>;
|
|
53
|
-
fetch?: typeof fetch;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/** Factory for MCP clients that forward the current async-context session. */
|
|
57
|
-
export class AgentCoreMcpClient {
|
|
58
|
-
/**
|
|
59
|
-
* Construct the invocation URL for an AgentCore runtime ARN and extract
|
|
60
|
-
* the region. ARN format: arn:partition:service:region:account-id:resource
|
|
61
|
-
*/
|
|
62
|
-
private static buildUrl(agentRuntimeArn: string): {
|
|
63
|
-
region: string;
|
|
64
|
-
url: string;
|
|
65
|
-
} {
|
|
66
|
-
const region = agentRuntimeArn.split(':')[3];
|
|
67
|
-
const url = `https://bedrock-agentcore.${region}.amazonaws.com/runtimes/${encodeURIComponent(agentRuntimeArn)}/invocations?qualifier=DEFAULT`;
|
|
68
|
-
return { region, url };
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
private static create(options: CreateOptions): McpClient {
|
|
72
|
-
const {
|
|
73
|
-
url,
|
|
74
|
-
buildHeaders = async (): Promise<Record<string, string>> => ({}),
|
|
75
|
-
fetch: customFetch,
|
|
76
|
-
} = options;
|
|
77
|
-
const fetchWithHeaders: typeof fetch = async (input, init) => {
|
|
78
|
-
const headers = new Headers(init?.headers);
|
|
79
|
-
const sessionId = getCurrentSessionId();
|
|
80
|
-
if (sessionId) headers.set(SESSION_HEADER, sessionId);
|
|
81
|
-
const extra = await buildHeaders();
|
|
82
|
-
for (const k of Object.keys(extra)) {
|
|
83
|
-
headers.set(k, extra[k]);
|
|
84
|
-
}
|
|
85
|
-
return (customFetch ?? fetch)(input, { ...init, headers });
|
|
86
|
-
};
|
|
87
|
-
const transport = new StreamableHTTPClientTransport(new URL(url), {
|
|
88
|
-
fetch: fetchWithHeaders,
|
|
89
|
-
});
|
|
90
|
-
return new McpClient({ transport });
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* SigV4-authenticated client for a Bedrock AgentCore runtime.
|
|
95
|
-
*/
|
|
96
|
-
static withIamAuth(options: AgentCoreMcpClientIamOptions): McpClient {
|
|
97
|
-
const { region, url } = AgentCoreMcpClient.buildUrl(options.agentRuntimeArn);
|
|
98
|
-
const credentialProvider =
|
|
99
|
-
options.credentialProvider ?? fromNodeProviderChain();
|
|
100
|
-
const sigv4Fetch: typeof fetch = async (...args) => {
|
|
101
|
-
const client = new AwsClient({
|
|
102
|
-
...(await credentialProvider()),
|
|
103
|
-
service: 'bedrock-agentcore',
|
|
104
|
-
region,
|
|
105
|
-
});
|
|
106
|
-
return client.fetch(...args);
|
|
107
|
-
};
|
|
108
|
-
return AgentCoreMcpClient.create({ url, fetch: sigv4Fetch });
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Bearer-authenticated client for a Bedrock AgentCore runtime.
|
|
113
|
-
*/
|
|
114
|
-
static withJwtAuth(options: AgentCoreMcpClientJwtOptions): McpClient {
|
|
115
|
-
const { url } = AgentCoreMcpClient.buildUrl(options.agentRuntimeArn);
|
|
116
|
-
return AgentCoreMcpClient.create({
|
|
117
|
-
url,
|
|
118
|
-
buildHeaders: async () => ({
|
|
119
|
-
Authorization: `Bearer ${await options.accessTokenProvider()}`,
|
|
120
|
-
}),
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/** For local dev — plain HTTP, no auth. */
|
|
125
|
-
static withoutAuth(options: AgentCoreMcpClientNoAuthOptions): McpClient {
|
|
126
|
-
return AgentCoreMcpClient.create({ url: options.url });
|
|
127
|
-
}
|
|
128
|
-
}
|
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
from collections.abc import Callable
|
|
2
|
-
from urllib.parse import quote
|
|
3
|
-
|
|
4
|
-
import boto3
|
|
5
|
-
import httpx
|
|
6
|
-
from a2a.client import ClientConfig
|
|
7
|
-
from strands.agent.a2a_agent import A2AAgent
|
|
8
|
-
|
|
9
|
-
from .auth import SigV4HTTPXAuth
|
|
10
|
-
from .session_context import get_current_session_id
|
|
11
|
-
|
|
12
|
-
SESSION_HEADER = "X-Amzn-Bedrock-AgentCore-Runtime-Session-Id"
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class _SessionHeaderAuth(httpx.Auth):
|
|
16
|
-
"""Stamps the AgentCore session header from the current async context."""
|
|
17
|
-
|
|
18
|
-
requires_request_body = True
|
|
19
|
-
requires_response_body = True
|
|
20
|
-
|
|
21
|
-
def __init__(self, inner: httpx.Auth | None = None):
|
|
22
|
-
self._inner = inner
|
|
23
|
-
|
|
24
|
-
def auth_flow(self, request: httpx.Request): # type: ignore[override]
|
|
25
|
-
sid = get_current_session_id()
|
|
26
|
-
if sid:
|
|
27
|
-
request.headers[SESSION_HEADER] = sid
|
|
28
|
-
if self._inner is None:
|
|
29
|
-
yield request
|
|
30
|
-
return
|
|
31
|
-
yield from self._inner.auth_flow(request)
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
class AgentCoreA2aClient:
|
|
35
|
-
"""Factory for A2A clients that forward the current async-context session."""
|
|
36
|
-
|
|
37
|
-
@staticmethod
|
|
38
|
-
def _build_url(agent_runtime_arn: str) -> tuple[str, str]:
|
|
39
|
-
"""Extract region from ARN and construct the A2A invocations URL.
|
|
40
|
-
|
|
41
|
-
ARN format: arn:partition:service:region:account-id:resource
|
|
42
|
-
A2A on AgentCore is mounted at `/invocations/` (trailing slash matters).
|
|
43
|
-
"""
|
|
44
|
-
region = agent_runtime_arn.split(":")[3]
|
|
45
|
-
encoded_arn = quote(agent_runtime_arn, safe="")
|
|
46
|
-
url = (
|
|
47
|
-
f"https://bedrock-agentcore.{region}.amazonaws.com/runtimes/"
|
|
48
|
-
f"{encoded_arn}/invocations/"
|
|
49
|
-
)
|
|
50
|
-
return region, url
|
|
51
|
-
|
|
52
|
-
@staticmethod
|
|
53
|
-
def _build(
|
|
54
|
-
url: str,
|
|
55
|
-
auth: httpx.Auth | None,
|
|
56
|
-
headers: dict | None,
|
|
57
|
-
*,
|
|
58
|
-
name: str | None,
|
|
59
|
-
description: str | None,
|
|
60
|
-
) -> A2AAgent:
|
|
61
|
-
httpx_client = httpx.AsyncClient(
|
|
62
|
-
auth=_SessionHeaderAuth(auth),
|
|
63
|
-
headers=headers or {},
|
|
64
|
-
timeout=120,
|
|
65
|
-
)
|
|
66
|
-
client_config = ClientConfig(httpx_client=httpx_client, streaming=False)
|
|
67
|
-
kwargs: dict = {"endpoint": url, "client_config": client_config}
|
|
68
|
-
if name:
|
|
69
|
-
kwargs["name"] = name
|
|
70
|
-
if description:
|
|
71
|
-
kwargs["description"] = description
|
|
72
|
-
return A2AAgent(**kwargs)
|
|
73
|
-
|
|
74
|
-
@staticmethod
|
|
75
|
-
def with_iam_auth(
|
|
76
|
-
agent_runtime_arn: str,
|
|
77
|
-
*,
|
|
78
|
-
name: str | None = None,
|
|
79
|
-
description: str | None = None,
|
|
80
|
-
) -> A2AAgent:
|
|
81
|
-
"""SigV4-authenticated client for a Bedrock AgentCore runtime."""
|
|
82
|
-
region, url = AgentCoreA2aClient._build_url(agent_runtime_arn)
|
|
83
|
-
credentials = boto3.Session(region_name=region).get_credentials()
|
|
84
|
-
return AgentCoreA2aClient._build(
|
|
85
|
-
url,
|
|
86
|
-
SigV4HTTPXAuth(credentials, "bedrock-agentcore", region),
|
|
87
|
-
None,
|
|
88
|
-
name=name,
|
|
89
|
-
description=description,
|
|
90
|
-
)
|
|
91
|
-
|
|
92
|
-
@staticmethod
|
|
93
|
-
def with_jwt_auth(
|
|
94
|
-
agent_runtime_arn: str,
|
|
95
|
-
access_token_provider: Callable[[], str],
|
|
96
|
-
*,
|
|
97
|
-
name: str | None = None,
|
|
98
|
-
description: str | None = None,
|
|
99
|
-
) -> A2AAgent:
|
|
100
|
-
"""Bearer-authenticated client for a Bedrock AgentCore runtime."""
|
|
101
|
-
_, url = AgentCoreA2aClient._build_url(agent_runtime_arn)
|
|
102
|
-
return AgentCoreA2aClient._build(
|
|
103
|
-
url,
|
|
104
|
-
None,
|
|
105
|
-
{"Authorization": f"Bearer {access_token_provider()}"},
|
|
106
|
-
name=name,
|
|
107
|
-
description=description,
|
|
108
|
-
)
|
|
109
|
-
|
|
110
|
-
@staticmethod
|
|
111
|
-
def without_auth(
|
|
112
|
-
url: str,
|
|
113
|
-
*,
|
|
114
|
-
name: str | None = None,
|
|
115
|
-
description: str | None = None,
|
|
116
|
-
) -> A2AAgent:
|
|
117
|
-
"""Plain-HTTP client — for local dev."""
|
|
118
|
-
return AgentCoreA2aClient._build(
|
|
119
|
-
url, None, None, name=name, description=description
|
|
120
|
-
)
|