@aws/nx-plugin 1.0.0-rc.58 → 1.0.0-rc.59

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 (96) hide show
  1. package/generators.json +17 -1
  2. package/migrations.json +12 -7
  3. package/package.json +1 -1
  4. package/src/agentcore-gateway/__snapshots__/generator.spec.ts.snap +273 -0
  5. package/src/agentcore-gateway/agent-connection/generator.d.ts +19 -0
  6. package/src/agentcore-gateway/agent-connection/generator.js +90 -0
  7. package/src/agentcore-gateway/agent-connection/generator.js.map +1 -0
  8. package/src/agentcore-gateway/agent-connection/schema.d.js +6 -0
  9. package/src/agentcore-gateway/agent-connection/schema.d.js.map +1 -0
  10. package/src/agentcore-gateway/agent-connection/schema.d.ts +13 -0
  11. package/src/agentcore-gateway/agent-connection/schema.json +31 -0
  12. package/src/agentcore-gateway/attach-upstream.d.ts +16 -0
  13. package/src/agentcore-gateway/attach-upstream.js +32 -11
  14. package/src/agentcore-gateway/attach-upstream.js.map +1 -1
  15. package/src/agentcore-gateway/files/project/http/local-dev.ts.template +77 -0
  16. package/src/agentcore-gateway/generator.d.ts +1 -0
  17. package/src/agentcore-gateway/generator.js +22 -10
  18. package/src/agentcore-gateway/generator.js.map +1 -1
  19. package/src/agentcore-gateway/react-connection/__snapshots__/generator.spec.ts.snap +68 -0
  20. package/src/agentcore-gateway/react-connection/generator.d.ts +19 -0
  21. package/src/agentcore-gateway/react-connection/generator.js +119 -0
  22. package/src/agentcore-gateway/react-connection/generator.js.map +1 -0
  23. package/src/agentcore-gateway/react-connection/schema.d.js +6 -0
  24. package/src/agentcore-gateway/react-connection/schema.d.js.map +1 -0
  25. package/src/agentcore-gateway/react-connection/schema.d.ts +13 -0
  26. package/src/agentcore-gateway/react-connection/schema.json +31 -0
  27. package/src/agentcore-gateway/schema.d.js.map +1 -1
  28. package/src/agentcore-gateway/schema.d.ts +1 -1
  29. package/src/agentcore-gateway/schema.json +2 -2
  30. package/src/connection/agent-local-dev.d.ts +16 -0
  31. package/src/connection/agent-local-dev.js +44 -2
  32. package/src/connection/agent-local-dev.js.map +1 -1
  33. package/src/connection/gateway-runtime-config.d.ts +19 -0
  34. package/src/connection/gateway-runtime-config.js +47 -0
  35. package/src/connection/gateway-runtime-config.js.map +1 -0
  36. package/src/connection/generator.js +5 -0
  37. package/src/connection/generator.js.map +1 -1
  38. package/src/connection/scaffold-catalog.d.ts +107 -0
  39. package/src/connection/scaffold-catalog.js +140 -0
  40. package/src/connection/scaffold-catalog.js.map +1 -1
  41. package/src/connection/supported-connections.d.ts +9 -0
  42. package/src/connection/supported-connections.js +12 -0
  43. package/src/connection/supported-connections.js.map +1 -1
  44. package/src/internal/test-matrix/generator.js +39 -1
  45. package/src/internal/test-matrix/generator.js.map +1 -1
  46. package/src/migrations/latest/gateway-agent-targets/__snapshots__/migration.spec.ts.snap +223 -0
  47. package/src/migrations/latest/gateway-agent-targets/metadata.json +3 -0
  48. package/src/migrations/latest/gateway-agent-targets/migration.d.ts +6 -0
  49. package/src/migrations/latest/gateway-agent-targets/migration.js +217 -0
  50. package/src/migrations/latest/gateway-agent-targets/migration.js.map +1 -0
  51. package/src/migrations/latest/smithy-ssdk-bundle-pins/metadata.json +3 -0
  52. package/src/migrations/v1.0.0-rc.50/modernize-function-props-cast/metadata.json +3 -0
  53. package/src/migrations/v1.0.0-rc.50/restrict-cors-to-custom-domains/metadata.json +3 -0
  54. package/src/migrations/v1.0.0-rc.50/terraform-bootstrap-adopt-existing-bucket/metadata.json +3 -0
  55. package/src/migrations/v1.0.0-rc.52/user-identity-waf-allow-localhost-callback/metadata.json +3 -0
  56. package/src/migrations/v1.0.0-rc.54/order-access-log-delivery-after-bucket-policy/metadata.json +3 -0
  57. package/src/migrations/v1.0.0-rc.55/backfill-generator-metadata/metadata.json +3 -0
  58. package/src/migrations/v1.0.0-rc.56/dynamodb-local-remove-optimize-flag/metadata.json +3 -0
  59. package/src/migrations/v1.0.0-rc.57/ts-agent-session-management-support/metadata.json +3 -0
  60. package/src/py/agent/__snapshots__/generator.constructs.spec.ts.snap +2 -0
  61. package/src/py/agent/react-connection/generator.d.ts +4 -1
  62. package/src/py/agent/react-connection/generator.js +35 -14
  63. package/src/py/agent/react-connection/generator.js.map +1 -1
  64. package/src/ts/agent/__snapshots__/generator.spec.ts.snap +4 -0
  65. package/src/ts/agent/react-connection/generator.d.ts +16 -1
  66. package/src/ts/agent/react-connection/generator.js +21 -8
  67. package/src/ts/agent/react-connection/generator.js.map +1 -1
  68. package/src/ts/nx-migration/generator.js +40 -27
  69. package/src/ts/nx-migration/generator.js.map +1 -1
  70. package/src/ts/react-website/agui/files/common/src/hooks/useAgui__agentNameClassName__.tsx.template +16 -0
  71. package/src/ts/react-website/agui/generator.d.ts +11 -0
  72. package/src/ts/react-website/agui/generator.js +11 -7
  73. package/src/ts/react-website/agui/generator.js.map +1 -1
  74. package/src/utils/agent-core-constructs/agent-core-constructs.d.ts +5 -0
  75. package/src/utils/agent-core-constructs/agent-core-constructs.js +2 -0
  76. package/src/utils/agent-core-constructs/agent-core-constructs.js.map +1 -1
  77. package/src/utils/agent-core-constructs/files/cdk/app/agent-core/__nameKebabCase__/__nameKebabCase__.ts.template +3 -0
  78. package/src/utils/agent-core-constructs/files/cdk/app/agentcore-gateway/__nameKebabCase__/__nameKebabCase__.ts.template +6 -4
  79. package/src/utils/agent-core-constructs/files/cdk/core/agentcore-gateway/agentcore-gateway.ts.template +119 -3
  80. package/src/utils/agent-core-constructs/files/terraform/app/agentcore-gateway/__nameKebabCase__/__nameKebabCase__.tf.template +17 -0
  81. package/src/utils/config/utils.d.ts +5 -0
  82. package/src/utils/config/utils.js +7 -1
  83. package/src/utils/config/utils.js.map +1 -1
  84. package/src/utils/connection/open-api/files/components/__apiNameClassName__Provider.tsx.template +13 -2
  85. package/src/utils/connection/open-api/react.d.ts +10 -1
  86. package/src/utils/connection/open-api/react.js +3 -2
  87. package/src/utils/connection/open-api/react.js.map +1 -1
  88. package/src/utils/migration-manifest.d.ts +58 -0
  89. package/src/utils/migration-manifest.js +76 -0
  90. package/src/utils/migration-manifest.js.map +1 -0
  91. package/src/utils/migration-versions.d.ts +2 -0
  92. package/src/utils/migration-versions.js.map +1 -1
  93. package/src/utils/version-upgrade-migration/register.d.ts +4 -2
  94. package/src/utils/version-upgrade-migration/register.js +13 -13
  95. package/src/utils/version-upgrade-migration/register.js.map +1 -1
  96. /package/src/agentcore-gateway/files/project/{local-dev.ts.template → mcp/local-dev.ts.template} +0 -0
@@ -0,0 +1,223 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`gateway-agent-targets migration > should add the agentName member to vended agent constructs 1`] = `
4
+ "import {
5
+ AgentRuntimeArtifact,
6
+ ProtocolType,
7
+ Runtime,
8
+ } from 'aws-cdk-lib/aws-bedrockagentcore';
9
+ import { Construct } from 'constructs';
10
+
11
+ export class MyAgent extends Construct {
12
+ public readonly dockerImage: AgentRuntimeArtifact;
13
+ public readonly agentCoreRuntime: Runtime;
14
+ /** Default Gateway target name for this agent. */
15
+ public readonly agentName = 'my-agent';
16
+
17
+ constructor(scope: Construct, id: string) {
18
+ super(scope, id);
19
+ this.agentCoreRuntime = undefined as any;
20
+ }
21
+ }
22
+ "
23
+ `;
24
+
25
+ exports[`gateway-agent-targets migration > should add the protocol prop and agent target methods to the vended gateway construct 1`] = `
26
+ "import * as cdk from 'aws-cdk-lib';
27
+ import * as agentcore from 'aws-cdk-lib/aws-bedrockagentcore';
28
+ import * as iam from 'aws-cdk-lib/aws-iam';
29
+ import * as triggers from 'aws-cdk-lib/triggers';
30
+ import * as wafv2 from 'aws-cdk-lib/aws-wafv2';
31
+ import { Construct } from 'constructs';
32
+
33
+ export interface AgentCoreGatewayProps {
34
+ readonly cedarPolicyPath?: string;
35
+ readonly cedarPolicyVariables?: Record<string, string>;
36
+ readonly enableWaf?: boolean;
37
+ readonly authorizer?: agentcore.IGatewayAuthorizerConfig;
38
+ /**
39
+ * The gateway's protocol. An \`mcp\` gateway aggregates MCP server targets
40
+ * into a single MCP endpoint. An \`http\` gateway has no protocol type and
41
+ * proxies requests to AgentCore Runtime targets via path-based routing
42
+ * (\`/<targetName>/invocations\`) — the target type AgentCore only allows on
43
+ * gateways without a protocol type.
44
+ *
45
+ * @default 'mcp'
46
+ */
47
+ readonly protocol?: 'mcp' | 'http';
48
+ }
49
+
50
+ export class AgentCoreGateway extends Construct implements iam.IGrantable {
51
+ public readonly gateway: agentcore.Gateway;
52
+ public readonly policyEngine?: agentcore.CfnPolicyEngine;
53
+ public readonly webAcl?: wafv2.CfnWebACL;
54
+ private readonly policies: agentcore.CfnPolicy[] = [];
55
+ private targetReadinessProbe?: triggers.TriggerFunction;
56
+ private readonly targetRuntimeArns: string[] = [];
57
+ private readonly protocol: 'mcp' | 'http';
58
+
59
+ constructor(scope: Construct, id: string, props?: AgentCoreGatewayProps) {
60
+ super(scope, id);
61
+
62
+ this.protocol = props?.protocol ?? 'mcp';
63
+
64
+ this.gateway = new agentcore.Gateway(this, 'Gateway', {
65
+ gatewayName: cdk.Names.uniqueResourceName(this, { maxLength: 39 }),
66
+ protocolConfiguration: new agentcore.McpProtocolConfiguration({
67
+ searchType: agentcore.McpGatewaySearchType.SEMANTIC,
68
+ supportedVersions: [agentcore.MCPProtocolVersion.MCP_2025_03_26],
69
+ }),
70
+ authorizerConfiguration:
71
+ props?.authorizer ?? agentcore.GatewayAuthorizer.usingAwsIam(),
72
+ });
73
+
74
+ if (this.protocol === 'http') {
75
+ // AgentCore Runtime targets require a gateway without a protocol type,
76
+ // which the Gateway L2 cannot express — it always renders MCP — so
77
+ // remove the protocol from the underlying CloudFormation resource.
78
+ const cfnGateway = this.gateway.node.defaultChild as agentcore.CfnGateway;
79
+ cfnGateway.addPropertyDeletionOverride('ProtocolType');
80
+ cfnGateway.addPropertyDeletionOverride('ProtocolConfiguration');
81
+ }
82
+ }
83
+
84
+ public get grantPrincipal(): iam.IPrincipal {
85
+ return this.gateway.role.grantPrincipal;
86
+ }
87
+
88
+ public addGatewayTarget(props: {
89
+ gatewayTargetName: string;
90
+ gatewayUrl: string;
91
+ gatewayArn: string;
92
+ }): agentcore.CfnGatewayTarget {
93
+ const target = this.addTarget(props.gatewayTargetName, props.gatewayUrl);
94
+
95
+ const grant = this.gateway.role.addToPrincipalPolicy(
96
+ new iam.PolicyStatement({
97
+ actions: ['bedrock-agentcore:InvokeGateway'],
98
+ resources: [props.gatewayArn],
99
+ }),
100
+ );
101
+ if (grant.policyDependable) {
102
+ target.node.addDependency(grant.policyDependable);
103
+ }
104
+
105
+ return target;
106
+ }
107
+
108
+ /**
109
+ * Add an agent runtime construct as a target of this Gateway. Requires the
110
+ * \`http\` protocol — the gateway proxies requests for the agent under
111
+ * \`<gatewayUrl>/<targetName>/invocations\`, without protocol translation.
112
+ *
113
+ * The target name defaults to the agent construct's \`agentName\` (its
114
+ * project's class name in kebab-case, e.g. \`MyAgent\` -> \`my-agent\`). It
115
+ * forms the target's invocation path, so renaming it later is a breaking
116
+ * change for consumers.
117
+ */
118
+ public addAgent(
119
+ agent: Construct & {
120
+ readonly agentCoreRuntime: agentcore.Runtime;
121
+ readonly agentName: string;
122
+ },
123
+ props?: {
124
+ gatewayTargetName?: string;
125
+ },
126
+ ): agentcore.CfnGatewayTarget {
127
+ return this.addAgentTarget({
128
+ gatewayTargetName: props?.gatewayTargetName ?? agent.agentName,
129
+ agentRuntimeArn: agent.agentCoreRuntime.agentRuntimeArn,
130
+ });
131
+ }
132
+
133
+ /**
134
+ * Register an agent runtime ARN as a Gateway target. Prefer
135
+ * {@link addAgent} when the construct is in scope.
136
+ */
137
+ public addAgentTarget(props: {
138
+ gatewayTargetName: string;
139
+ agentRuntimeArn: string;
140
+ }): agentcore.CfnGatewayTarget {
141
+ if (this.protocol !== 'http') {
142
+ throw new Error(
143
+ \`Agent runtime targets require an http-protocol gateway, but this gateway uses '\${this.protocol}'.\`,
144
+ );
145
+ }
146
+
147
+ // The construct id is derived from the target name so the two change
148
+ // together — target names are unique per gateway, and replacing a target
149
+ // under an unchanged name fails with AlreadyExists.
150
+ const target = new agentcore.CfnGatewayTarget(
151
+ this,
152
+ \`Target-\${props.gatewayTargetName}\`,
153
+ {
154
+ gatewayIdentifier: this.gateway.gatewayId,
155
+ name: props.gatewayTargetName,
156
+ targetConfiguration: {
157
+ http: {
158
+ agentcoreRuntime: {
159
+ arn: props.agentRuntimeArn,
160
+ qualifier: 'DEFAULT',
161
+ },
162
+ },
163
+ },
164
+ // The bare gateway IAM role credential: runtime targets reject the
165
+ // iamCredentialProvider detail MCP targets carry.
166
+ credentialProviderConfigurations: [
167
+ {
168
+ credentialProviderType: 'GATEWAY_IAM_ROLE',
169
+ },
170
+ ],
171
+ },
172
+ );
173
+
174
+ // Grant the gateway role invoke access to the target runtime before the
175
+ // target is created — AgentCore validates access to the runtime during
176
+ // target creation.
177
+ const grant = this.gateway.role.addToPrincipalPolicy(
178
+ new iam.PolicyStatement({
179
+ actions: [
180
+ 'bedrock-agentcore:InvokeAgentRuntime',
181
+ 'bedrock-agentcore:InvokeAgentRuntimeWithWebSocketStream',
182
+ // A2A targets additionally serve their agent card via the gateway.
183
+ 'bedrock-agentcore:GetAgentCard',
184
+ ],
185
+ resources: [props.agentRuntimeArn, \`\${props.agentRuntimeArn}/*\`],
186
+ }),
187
+ );
188
+ if (grant.policyDependable) {
189
+ target.node.addDependency(grant.policyDependable);
190
+ }
191
+
192
+ return target;
193
+ }
194
+
195
+ private addTarget(
196
+ gatewayTargetName: string,
197
+ endpoint: string,
198
+ ): agentcore.CfnGatewayTarget {
199
+ const target = new agentcore.CfnGatewayTarget(
200
+ this,
201
+ \`Target-\${gatewayTargetName}\`,
202
+ {
203
+ gatewayIdentifier: this.gateway.gatewayId,
204
+ name: gatewayTargetName,
205
+ targetConfiguration: {
206
+ mcp: {
207
+ mcpServer: {
208
+ endpoint,
209
+ },
210
+ },
211
+ },
212
+ },
213
+ );
214
+
215
+ for (const policy of this.policies) {
216
+ policy.node.addDependency(target);
217
+ }
218
+
219
+ return target;
220
+ }
221
+ }
222
+ "
223
+ `;
@@ -0,0 +1,3 @@
1
+ {
2
+ "description": "Add agent runtime target support to the vended AgentCoreGateway construct and an agentName member to vended agent constructs"
3
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ import type { MigrationReturnObject, Tree } from '@nx/devkit';
6
+ export default function migration(tree: Tree): Promise<MigrationReturnObject>;
@@ -0,0 +1,217 @@
1
+ /**
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */ import { applyGritQL, GRIT_INSERT_PLACEHOLDER, insertViaGritQL, matchGritQL } from "../../../utils/ast.js";
5
+ import { formatFilesInSubtree } from "../../../utils/format.js";
6
+ import { PACKAGES_DIR, SHARED_CONSTRUCTS_DIR } from "../../../utils/shared-constructs-constants.js";
7
+ /**
8
+ * Bring existing workspaces up to the generators' current gateway-target
9
+ * support, so agents can be attached to an http-protocol AgentCore Gateway:
10
+ *
11
+ * - The vended `AgentCoreGateway` core construct gains the `protocol` prop
12
+ * (http gateways have no protocol type, which AgentCore Runtime targets
13
+ * require) and the `addAgent` / `addAgentTarget` methods.
14
+ * - Vended agent constructs gain the `agentName` member `addAgent` reads as
15
+ * the default gateway target name.
16
+ *
17
+ * Both files are generated with `KeepExisting`, so without this an upgraded
18
+ * workspace pairs new app-level constructs with stale core ones.
19
+ */ const GATEWAY_CONSTRUCT_FILE = `${PACKAGES_DIR}/${SHARED_CONSTRUCTS_DIR}/src/core/agentcore-gateway/agentcore-gateway.ts`;
20
+ const AGENTS_DIR = `${PACKAGES_DIR}/${SHARED_CONSTRUCTS_DIR}/src/app/agents`;
21
+ const PROTOCOL_PROP = `/**
22
+ * The gateway's protocol. An \`mcp\` gateway aggregates MCP server targets
23
+ * into a single MCP endpoint. An \`http\` gateway has no protocol type and
24
+ * proxies requests to AgentCore Runtime targets via path-based routing
25
+ * (\`/<targetName>/invocations\`) — the target type AgentCore only allows on
26
+ * gateways without a protocol type.
27
+ *
28
+ * @default 'mcp'
29
+ */
30
+ readonly protocol?: 'mcp' | 'http';`;
31
+ const PROTOCOL_CONSTRUCTOR_STATEMENTS = `this.protocol = props?.protocol ?? 'mcp';
32
+ `;
33
+ const PROTOCOL_TYPE_REMOVAL = `
34
+ if (this.protocol === 'http') {
35
+ // AgentCore Runtime targets require a gateway without a protocol type,
36
+ // which the Gateway L2 cannot express — it always renders MCP — so
37
+ // remove the protocol from the underlying CloudFormation resource.
38
+ const cfnGateway = this.gateway.node.defaultChild as agentcore.CfnGateway;
39
+ cfnGateway.addPropertyDeletionOverride('ProtocolType');
40
+ cfnGateway.addPropertyDeletionOverride('ProtocolConfiguration');
41
+ }`;
42
+ const AGENT_TARGET_METHODS = `
43
+ /**
44
+ * Add an agent runtime construct as a target of this Gateway. Requires the
45
+ * \`http\` protocol — the gateway proxies requests for the agent under
46
+ * \`<gatewayUrl>/<targetName>/invocations\`, without protocol translation.
47
+ *
48
+ * The target name defaults to the agent construct's \`agentName\` (its
49
+ * project's class name in kebab-case, e.g. \`MyAgent\` -> \`my-agent\`). It
50
+ * forms the target's invocation path, so renaming it later is a breaking
51
+ * change for consumers.
52
+ */
53
+ public addAgent(
54
+ agent: Construct & {
55
+ readonly agentCoreRuntime: agentcore.Runtime;
56
+ readonly agentName: string;
57
+ },
58
+ props?: {
59
+ gatewayTargetName?: string;
60
+ },
61
+ ): agentcore.CfnGatewayTarget {
62
+ return this.addAgentTarget({
63
+ gatewayTargetName: props?.gatewayTargetName ?? agent.agentName,
64
+ agentRuntimeArn: agent.agentCoreRuntime.agentRuntimeArn,
65
+ });
66
+ }
67
+
68
+ /**
69
+ * Register an agent runtime ARN as a Gateway target. Prefer
70
+ * {@link addAgent} when the construct is in scope.
71
+ */
72
+ public addAgentTarget(props: {
73
+ gatewayTargetName: string;
74
+ agentRuntimeArn: string;
75
+ }): agentcore.CfnGatewayTarget {
76
+ if (this.protocol !== 'http') {
77
+ throw new Error(
78
+ \`Agent runtime targets require an http-protocol gateway, but this gateway uses '\${this.protocol}'.\`,
79
+ );
80
+ }
81
+
82
+ // The construct id is derived from the target name so the two change
83
+ // together — target names are unique per gateway, and replacing a target
84
+ // under an unchanged name fails with AlreadyExists.
85
+ const target = new agentcore.CfnGatewayTarget(
86
+ this,
87
+ \`Target-\${props.gatewayTargetName}\`,
88
+ {
89
+ gatewayIdentifier: this.gateway.gatewayId,
90
+ name: props.gatewayTargetName,
91
+ targetConfiguration: {
92
+ http: {
93
+ agentcoreRuntime: {
94
+ arn: props.agentRuntimeArn,
95
+ qualifier: 'DEFAULT',
96
+ },
97
+ },
98
+ },
99
+ // The bare gateway IAM role credential: runtime targets reject the
100
+ // iamCredentialProvider detail MCP targets carry.
101
+ credentialProviderConfigurations: [
102
+ {
103
+ credentialProviderType: 'GATEWAY_IAM_ROLE',
104
+ },
105
+ ],
106
+ },
107
+ );
108
+
109
+ // Grant the gateway role invoke access to the target runtime before the
110
+ // target is created — AgentCore validates access to the runtime during
111
+ // target creation.
112
+ const grant = this.gateway.role.addToPrincipalPolicy(
113
+ new iam.PolicyStatement({
114
+ actions: [
115
+ 'bedrock-agentcore:InvokeAgentRuntime',
116
+ 'bedrock-agentcore:InvokeAgentRuntimeWithWebSocketStream',
117
+ // A2A targets additionally serve their agent card via the gateway.
118
+ 'bedrock-agentcore:GetAgentCard',
119
+ ],
120
+ resources: [props.agentRuntimeArn, \`\${props.agentRuntimeArn}/*\`],
121
+ }),
122
+ );
123
+ if (grant.policyDependable) {
124
+ target.node.addDependency(grant.policyDependable);
125
+ }
126
+
127
+ return target;
128
+ }`;
129
+ /**
130
+ * Add the `protocol` prop, its constructor handling and the agent-target
131
+ * methods to the vended `AgentCoreGateway` core construct.
132
+ */ const migrateGatewayConstruct = async (tree, nextSteps)=>{
133
+ if (!tree.exists(GATEWAY_CONSTRUCT_FILE)) {
134
+ // No vended gateway construct in this workspace - nothing to migrate.
135
+ return;
136
+ }
137
+ if ((tree.read(GATEWAY_CONSTRUCT_FILE, 'utf-8') ?? '').includes('addAgentTarget')) {
138
+ // Already migrated.
139
+ return;
140
+ }
141
+ const divergedMessage = `${GATEWAY_CONSTRUCT_FILE}: the AgentCoreGateway construct has diverged from the generated shape - left untouched. Re-run the agentcore-gateway generator in a fresh workspace to see the current construct, which supports agent runtime targets via a 'protocol' prop and addAgent()/addAgentTarget() methods.`;
142
+ // Anchored on the shapes every vended version of the construct carries: the
143
+ // props interface, the class field the protocol field is inserted after,
144
+ // and the Gateway creation in the constructor.
145
+ const hasVendedShape = await matchGritQL(tree, GATEWAY_CONSTRUCT_FILE, '`export interface AgentCoreGatewayProps { $_ }`') && await matchGritQL(tree, GATEWAY_CONSTRUCT_FILE, '`private readonly targetRuntimeArns: string[] = []`') && await matchGritQL(tree, GATEWAY_CONSTRUCT_FILE, "`this.gateway = new agentcore.Gateway(this, 'Gateway', $_)`");
146
+ if (!hasVendedShape) {
147
+ nextSteps.push(divergedMessage);
148
+ return;
149
+ }
150
+ // 1. The protocol prop on AgentCoreGatewayProps. The placeholder keeps the
151
+ // prop's doc comment (with its backticks) out of the GritQL pattern.
152
+ await insertViaGritQL(tree, GATEWAY_CONSTRUCT_FILE, `\`export interface AgentCoreGatewayProps { $members }\` where {
153
+ $members <: not contains \`protocol\`
154
+ } => \`export interface AgentCoreGatewayProps { $members
155
+ ${GRIT_INSERT_PLACEHOLDER}
156
+ }\``, PROTOCOL_PROP);
157
+ // 2. The protocol class field. Matched without the trailing semicolon —
158
+ // GritQL parses the snippet standalone, where the semicolon is not part
159
+ // of the field's AST node.
160
+ await applyGritQL(tree, GATEWAY_CONSTRUCT_FILE, `\`private readonly targetRuntimeArns: string[] = []\` as $field where {
161
+ $program <: not contains \`private readonly protocol\`
162
+ } => \`$field;
163
+ private readonly protocol: 'mcp' | 'http'\``);
164
+ // 3. Assign the field and remove the protocol type for http gateways.
165
+ await insertViaGritQL(tree, GATEWAY_CONSTRUCT_FILE, `\`this.gateway = new agentcore.Gateway($args);\` as $stmt where {
166
+ $program <: not contains \`this.protocol = props\`
167
+ } => \`${GRIT_INSERT_PLACEHOLDER}
168
+ $stmt\``, PROTOCOL_CONSTRUCTOR_STATEMENTS);
169
+ await insertViaGritQL(tree, GATEWAY_CONSTRUCT_FILE, `\`this.gateway = new agentcore.Gateway($args);\` as $stmt where {
170
+ $program <: not contains \`addPropertyDeletionOverride\`
171
+ } => \`$stmt
172
+ ${GRIT_INSERT_PLACEHOLDER}\``, PROTOCOL_TYPE_REMOVAL);
173
+ // 4. The agent-target methods, inserted after addGatewayTarget (present in
174
+ // every vended version that also has the readiness probe field).
175
+ const addedMethods = await insertViaGritQL(tree, GATEWAY_CONSTRUCT_FILE, `\`public addGatewayTarget($params): agentcore.CfnGatewayTarget { $body }\` as $method where {
176
+ $program <: not contains \`addAgentTarget\`
177
+ } => \`$method
178
+ ${GRIT_INSERT_PLACEHOLDER}\``, AGENT_TARGET_METHODS);
179
+ if (!addedMethods) {
180
+ nextSteps.push(divergedMessage);
181
+ return;
182
+ }
183
+ };
184
+ /**
185
+ * Add the `agentName` member to each vended agent construct, which
186
+ * `AgentCoreGateway.addAgent` reads as the default gateway target name.
187
+ */ const migrateAgentConstructs = async (tree, nextSteps)=>{
188
+ if (!tree.exists(AGENTS_DIR)) {
189
+ return;
190
+ }
191
+ for (const dir of tree.children(AGENTS_DIR)){
192
+ const constructFile = `${AGENTS_DIR}/${dir}/${dir}.ts`;
193
+ if (!tree.exists(constructFile)) {
194
+ continue;
195
+ }
196
+ if ((tree.read(constructFile, 'utf-8') ?? '').includes('agentName')) {
197
+ continue;
198
+ }
199
+ const added = await insertViaGritQL(tree, constructFile, `\`public readonly agentCoreRuntime: Runtime\` as $field => \`$field;
200
+ ${GRIT_INSERT_PLACEHOLDER}\``, `/** Default Gateway target name for this agent. */
201
+ public readonly agentName = '${dir}'`);
202
+ if (!added) {
203
+ nextSteps.push(`${constructFile}: the agent construct has diverged from the generated shape - left untouched. To attach this agent to a gateway with addAgent(), add a \`public readonly agentName = '${dir}';\` member (or use addAgentTarget() with an explicit target name).`);
204
+ }
205
+ }
206
+ };
207
+ export default async function migration(tree) {
208
+ const nextSteps = [];
209
+ await migrateGatewayConstruct(tree, nextSteps);
210
+ await migrateAgentConstructs(tree, nextSteps);
211
+ await formatFilesInSubtree(tree);
212
+ return {
213
+ nextSteps
214
+ };
215
+ }
216
+
217
+ //# sourceMappingURL=migration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/latest/gateway-agent-targets/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { MigrationReturnObject, Tree } from '@nx/devkit';\nimport {\n applyGritQL,\n GRIT_INSERT_PLACEHOLDER,\n insertViaGritQL,\n matchGritQL,\n} from '../../../utils/ast';\nimport { formatFilesInSubtree } from '../../../utils/format';\nimport {\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n} from '../../../utils/shared-constructs-constants';\n\n/**\n * Bring existing workspaces up to the generators' current gateway-target\n * support, so agents can be attached to an http-protocol AgentCore Gateway:\n *\n * - The vended `AgentCoreGateway` core construct gains the `protocol` prop\n * (http gateways have no protocol type, which AgentCore Runtime targets\n * require) and the `addAgent` / `addAgentTarget` methods.\n * - Vended agent constructs gain the `agentName` member `addAgent` reads as\n * the default gateway target name.\n *\n * Both files are generated with `KeepExisting`, so without this an upgraded\n * workspace pairs new app-level constructs with stale core ones.\n */\n\nconst GATEWAY_CONSTRUCT_FILE = `${PACKAGES_DIR}/${SHARED_CONSTRUCTS_DIR}/src/core/agentcore-gateway/agentcore-gateway.ts`;\n\nconst AGENTS_DIR = `${PACKAGES_DIR}/${SHARED_CONSTRUCTS_DIR}/src/app/agents`;\n\nconst PROTOCOL_PROP = `/**\n * The gateway's protocol. An \\`mcp\\` gateway aggregates MCP server targets\n * into a single MCP endpoint. An \\`http\\` gateway has no protocol type and\n * proxies requests to AgentCore Runtime targets via path-based routing\n * (\\`/<targetName>/invocations\\`) — the target type AgentCore only allows on\n * gateways without a protocol type.\n *\n * @default 'mcp'\n */\n readonly protocol?: 'mcp' | 'http';`;\n\nconst PROTOCOL_CONSTRUCTOR_STATEMENTS = `this.protocol = props?.protocol ?? 'mcp';\n`;\n\nconst PROTOCOL_TYPE_REMOVAL = `\n if (this.protocol === 'http') {\n // AgentCore Runtime targets require a gateway without a protocol type,\n // which the Gateway L2 cannot express — it always renders MCP — so\n // remove the protocol from the underlying CloudFormation resource.\n const cfnGateway = this.gateway.node.defaultChild as agentcore.CfnGateway;\n cfnGateway.addPropertyDeletionOverride('ProtocolType');\n cfnGateway.addPropertyDeletionOverride('ProtocolConfiguration');\n }`;\n\nconst AGENT_TARGET_METHODS = `\n /**\n * Add an agent runtime construct as a target of this Gateway. Requires the\n * \\`http\\` protocol — the gateway proxies requests for the agent under\n * \\`<gatewayUrl>/<targetName>/invocations\\`, without protocol translation.\n *\n * The target name defaults to the agent construct's \\`agentName\\` (its\n * project's class name in kebab-case, e.g. \\`MyAgent\\` -> \\`my-agent\\`). It\n * forms the target's invocation path, so renaming it later is a breaking\n * change for consumers.\n */\n public addAgent(\n agent: Construct & {\n readonly agentCoreRuntime: agentcore.Runtime;\n readonly agentName: string;\n },\n props?: {\n gatewayTargetName?: string;\n },\n ): agentcore.CfnGatewayTarget {\n return this.addAgentTarget({\n gatewayTargetName: props?.gatewayTargetName ?? agent.agentName,\n agentRuntimeArn: agent.agentCoreRuntime.agentRuntimeArn,\n });\n }\n\n /**\n * Register an agent runtime ARN as a Gateway target. Prefer\n * {@link addAgent} when the construct is in scope.\n */\n public addAgentTarget(props: {\n gatewayTargetName: string;\n agentRuntimeArn: string;\n }): agentcore.CfnGatewayTarget {\n if (this.protocol !== 'http') {\n throw new Error(\n \\`Agent runtime targets require an http-protocol gateway, but this gateway uses '\\${this.protocol}'.\\`,\n );\n }\n\n // The construct id is derived from the target name so the two change\n // together — target names are unique per gateway, and replacing a target\n // under an unchanged name fails with AlreadyExists.\n const target = new agentcore.CfnGatewayTarget(\n this,\n \\`Target-\\${props.gatewayTargetName}\\`,\n {\n gatewayIdentifier: this.gateway.gatewayId,\n name: props.gatewayTargetName,\n targetConfiguration: {\n http: {\n agentcoreRuntime: {\n arn: props.agentRuntimeArn,\n qualifier: 'DEFAULT',\n },\n },\n },\n // The bare gateway IAM role credential: runtime targets reject the\n // iamCredentialProvider detail MCP targets carry.\n credentialProviderConfigurations: [\n {\n credentialProviderType: 'GATEWAY_IAM_ROLE',\n },\n ],\n },\n );\n\n // Grant the gateway role invoke access to the target runtime before the\n // target is created — AgentCore validates access to the runtime during\n // target creation.\n const grant = this.gateway.role.addToPrincipalPolicy(\n new iam.PolicyStatement({\n actions: [\n 'bedrock-agentcore:InvokeAgentRuntime',\n 'bedrock-agentcore:InvokeAgentRuntimeWithWebSocketStream',\n // A2A targets additionally serve their agent card via the gateway.\n 'bedrock-agentcore:GetAgentCard',\n ],\n resources: [props.agentRuntimeArn, \\`\\${props.agentRuntimeArn}/*\\`],\n }),\n );\n if (grant.policyDependable) {\n target.node.addDependency(grant.policyDependable);\n }\n\n return target;\n }`;\n\n/**\n * Add the `protocol` prop, its constructor handling and the agent-target\n * methods to the vended `AgentCoreGateway` core construct.\n */\nconst migrateGatewayConstruct = async (\n tree: Tree,\n nextSteps: string[],\n): Promise<void> => {\n if (!tree.exists(GATEWAY_CONSTRUCT_FILE)) {\n // No vended gateway construct in this workspace - nothing to migrate.\n return;\n }\n\n if (\n (tree.read(GATEWAY_CONSTRUCT_FILE, 'utf-8') ?? '').includes(\n 'addAgentTarget',\n )\n ) {\n // Already migrated.\n return;\n }\n\n const divergedMessage = `${GATEWAY_CONSTRUCT_FILE}: the AgentCoreGateway construct has diverged from the generated shape - left untouched. Re-run the agentcore-gateway generator in a fresh workspace to see the current construct, which supports agent runtime targets via a 'protocol' prop and addAgent()/addAgentTarget() methods.`;\n\n // Anchored on the shapes every vended version of the construct carries: the\n // props interface, the class field the protocol field is inserted after,\n // and the Gateway creation in the constructor.\n const hasVendedShape =\n (await matchGritQL(\n tree,\n GATEWAY_CONSTRUCT_FILE,\n '`export interface AgentCoreGatewayProps { $_ }`',\n )) &&\n (await matchGritQL(\n tree,\n GATEWAY_CONSTRUCT_FILE,\n '`private readonly targetRuntimeArns: string[] = []`',\n )) &&\n (await matchGritQL(\n tree,\n GATEWAY_CONSTRUCT_FILE,\n \"`this.gateway = new agentcore.Gateway(this, 'Gateway', $_)`\",\n ));\n\n if (!hasVendedShape) {\n nextSteps.push(divergedMessage);\n return;\n }\n\n // 1. The protocol prop on AgentCoreGatewayProps. The placeholder keeps the\n // prop's doc comment (with its backticks) out of the GritQL pattern.\n await insertViaGritQL(\n tree,\n GATEWAY_CONSTRUCT_FILE,\n `\\`export interface AgentCoreGatewayProps { $members }\\` where {\n $members <: not contains \\`protocol\\`\n} => \\`export interface AgentCoreGatewayProps { $members\n ${GRIT_INSERT_PLACEHOLDER}\n}\\``,\n PROTOCOL_PROP,\n );\n\n // 2. The protocol class field. Matched without the trailing semicolon —\n // GritQL parses the snippet standalone, where the semicolon is not part\n // of the field's AST node.\n await applyGritQL(\n tree,\n GATEWAY_CONSTRUCT_FILE,\n `\\`private readonly targetRuntimeArns: string[] = []\\` as $field where {\n $program <: not contains \\`private readonly protocol\\`\n} => \\`$field;\n private readonly protocol: 'mcp' | 'http'\\``,\n );\n\n // 3. Assign the field and remove the protocol type for http gateways.\n await insertViaGritQL(\n tree,\n GATEWAY_CONSTRUCT_FILE,\n `\\`this.gateway = new agentcore.Gateway($args);\\` as $stmt where {\n $program <: not contains \\`this.protocol = props\\`\n} => \\`${GRIT_INSERT_PLACEHOLDER}\n $stmt\\``,\n PROTOCOL_CONSTRUCTOR_STATEMENTS,\n );\n await insertViaGritQL(\n tree,\n GATEWAY_CONSTRUCT_FILE,\n `\\`this.gateway = new agentcore.Gateway($args);\\` as $stmt where {\n $program <: not contains \\`addPropertyDeletionOverride\\`\n} => \\`$stmt\n${GRIT_INSERT_PLACEHOLDER}\\``,\n PROTOCOL_TYPE_REMOVAL,\n );\n\n // 4. The agent-target methods, inserted after addGatewayTarget (present in\n // every vended version that also has the readiness probe field).\n const addedMethods = await insertViaGritQL(\n tree,\n GATEWAY_CONSTRUCT_FILE,\n `\\`public addGatewayTarget($params): agentcore.CfnGatewayTarget { $body }\\` as $method where {\n $program <: not contains \\`addAgentTarget\\`\n} => \\`$method\n${GRIT_INSERT_PLACEHOLDER}\\``,\n AGENT_TARGET_METHODS,\n );\n\n if (!addedMethods) {\n nextSteps.push(divergedMessage);\n return;\n }\n};\n\n/**\n * Add the `agentName` member to each vended agent construct, which\n * `AgentCoreGateway.addAgent` reads as the default gateway target name.\n */\nconst migrateAgentConstructs = async (\n tree: Tree,\n nextSteps: string[],\n): Promise<void> => {\n if (!tree.exists(AGENTS_DIR)) {\n return;\n }\n for (const dir of tree.children(AGENTS_DIR)) {\n const constructFile = `${AGENTS_DIR}/${dir}/${dir}.ts`;\n if (!tree.exists(constructFile)) {\n continue;\n }\n if ((tree.read(constructFile, 'utf-8') ?? '').includes('agentName')) {\n // Already migrated (or user-added).\n continue;\n }\n const added = await insertViaGritQL(\n tree,\n constructFile,\n `\\`public readonly agentCoreRuntime: Runtime\\` as $field => \\`$field;\n ${GRIT_INSERT_PLACEHOLDER}\\``,\n `/** Default Gateway target name for this agent. */\n public readonly agentName = '${dir}'`,\n );\n if (!added) {\n nextSteps.push(\n `${constructFile}: the agent construct has diverged from the generated shape - left untouched. To attach this agent to a gateway with addAgent(), add a \\`public readonly agentName = '${dir}';\\` member (or use addAgentTarget() with an explicit target name).`,\n );\n }\n }\n};\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n\n await migrateGatewayConstruct(tree, nextSteps);\n await migrateAgentConstructs(tree, nextSteps);\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["applyGritQL","GRIT_INSERT_PLACEHOLDER","insertViaGritQL","matchGritQL","formatFilesInSubtree","PACKAGES_DIR","SHARED_CONSTRUCTS_DIR","GATEWAY_CONSTRUCT_FILE","AGENTS_DIR","PROTOCOL_PROP","PROTOCOL_CONSTRUCTOR_STATEMENTS","PROTOCOL_TYPE_REMOVAL","AGENT_TARGET_METHODS","migrateGatewayConstruct","tree","nextSteps","exists","read","includes","divergedMessage","hasVendedShape","push","addedMethods","migrateAgentConstructs","dir","children","constructFile","added","migration"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ {
2
+ "description": "Bump the rolldown and dts plugin pins in the Smithy build.Dockerfile so the bundled SSDK type declaration resolves"
3
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "description": "Replace the legacy angle-bracket FunctionProps type assertion with the modern as syntax in generated API constructs"
3
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "description": "Include CloudFront custom domain aliases in restrictCorsTo and UserIdentity callback URLs"
3
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "description": "Adopt an existing Terraform state bucket in the vended bootstrap script when its state object is missing"
3
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "description": "Count the EC2MetaDataSSRF_QUERYARGUMENTS WAF rule on the UserIdentity Web ACL so sign-in from a local dev server is not blocked"
3
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "description": "Order the S3 server access log delivery source after the bucket policy to avoid a 409 from concurrent bucket configuration writes"
3
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "description": "Backfill the project metadata the version sync reads, recovered from the files the generators left behind"
3
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "description": "Drop -optimizeDbBeforeStartup from the vended DynamoDB Local container script, which can corrupt shared-local-instance.db"
3
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "description": "Add session management support to ts#agent"
3
+ }
@@ -55,6 +55,8 @@ export class SnapshotBedrockAgent
55
55
  {
56
56
  public readonly dockerImage: AgentRuntimeArtifact;
57
57
  public readonly agentCoreRuntime: Runtime;
58
+ /** Default Gateway target name for this agent. */
59
+ public readonly agentName = 'snapshot-bedrock-agent';
58
60
 
59
61
  constructor(scope: Construct, id: string, props?: SnapshotBedrockAgentProps) {
60
62
  super(scope, id);
@@ -4,6 +4,7 @@
4
4
  */
5
5
  import { type Tree } from '@nx/devkit';
6
6
  import type { ResolvedConnectionOptions } from '../../../connection/generator';
7
+ import type { AgentGatewayRoute } from '../../../ts/agent/react-connection/generator';
7
8
  import { type NxGeneratorInfo } from '../../../utils/nx';
8
9
  /** The metadata this generator records, which its predicates read. */
9
10
  export interface PyAgentReactConnectionMetadata {
@@ -152,5 +153,7 @@ export declare const DEPENDENCIES: import("../../../utils/declared-dependencies"
152
153
  when: (m: PyAgentReactConnectionMetadata) => boolean;
153
154
  }], readonly import("../../../utils/declared-dependencies").DeclaredPyDependency<"a2a-sdk" | "ag-ui-langgraph" | "ag-ui-protocol" | "ag-ui-strands" | "aws-lambda-powertools" | "aws-lambda-powertools[tracer]" | "aws-lambda-powertools[parser]" | "aws-opentelemetry-distro" | "bedrock-agentcore" | "boto3" | "checkov" | "fastapi" | "fastapi[standard]" | "httpx" | "langchain" | "langchain-aws" | "langchain-mcp-adapters" | "langgraph" | "mcp" | "pip-check-updates" | "pip-licenses" | "ruff" | "strands-agents" | "strands-agents[a2a]" | "strands-agents-tools" | "ty" | "pynamodb" | "uvicorn" | "sqlmodel" | "alembic" | "aiomysql" | "asyncpg" | "greenlet", PyAgentReactConnectionMetadata>[]>;
154
155
  export declare const PY_AGENT_REACT_CONNECTION_GENERATOR_INFO: NxGeneratorInfo;
155
- export declare const pyAgentReactConnectionGenerator: (tree: Tree, options: ResolvedConnectionOptions) => Promise<() => Promise<void>>;
156
+ export declare const pyAgentReactConnectionGenerator: (tree: Tree, options: ResolvedConnectionOptions & {
157
+ gatewayRoute?: AgentGatewayRoute;
158
+ }) => Promise<() => Promise<void>>;
156
159
  export default pyAgentReactConnectionGenerator;
@@ -10,7 +10,7 @@ import { formatFilesInSubtree } from "../../../utils/format.js";
10
10
  import { installDependencies } from "../../../utils/install.js";
11
11
  import { addGeneratorMetricsIfApplicable } from "../../../utils/metrics.js";
12
12
  import { kebabCase, toClassName, toSnakeCase } from "../../../utils/names.js";
13
- import { addComponentGeneratorMetadata, getGeneratorInfo, readProjectConfigurationUnqualified } from "../../../utils/nx.js";
13
+ import { addComponentGeneratorMetadata, addDependencyToTargetIfNotPresent, getGeneratorInfo, readProjectConfigurationUnqualified } from "../../../utils/nx.js";
14
14
  import { sortObjectKeys } from "../../../utils/object.js";
15
15
  import { toProjectRelativePath } from "../../../utils/paths.js";
16
16
  import { addPyAgentTargetToLocalDev, openApiClientLocalDevDeps } from "./local-dev.js";
@@ -36,7 +36,8 @@ export const pyAgentReactConnectionGenerator = async (tree, options)=>{
36
36
  const agentName = targetComponent?.name ?? 'agent';
37
37
  const agentNameClassName = targetComponent?.rc ?? toClassName(agentName);
38
38
  const agentPort = targetComponent?.port ?? metadata?.ports?.[0] ?? 8081;
39
- const auth = (targetComponent?.auth ?? metadata?.auth ?? 'iam').toLowerCase();
39
+ // Behind a gateway the browser authenticates with the gateway, not the agent.
40
+ const auth = (options.gatewayRoute?.gatewayAuth ?? targetComponent?.auth ?? metadata?.auth ?? 'iam').toLowerCase();
40
41
  const protocol = (targetComponent?.protocol ?? 'http').toLowerCase();
41
42
  // Recorded below and read by the declaration's predicates, so the packages
42
43
  // added here are exactly the ones the version sync will own.
@@ -54,7 +55,8 @@ export const pyAgentReactConnectionGenerator = async (tree, options)=>{
54
55
  frontendProjectConfig,
55
56
  agentName,
56
57
  agentNameClassName,
57
- auth: auth
58
+ auth: auth,
59
+ gatewayRoute: options.gatewayRoute
58
60
  });
59
61
  } else {
60
62
  const moduleName = getModuleName(agentProjectConfig);
@@ -101,25 +103,44 @@ export const pyAgentReactConnectionGenerator = async (tree, options)=>{
101
103
  auth,
102
104
  port: agentPort,
103
105
  isAgentRuntime: true,
106
+ gatewayRoute: options.gatewayRoute,
104
107
  skipLocalDev: true
105
108
  }, DEPENDENCIES);
106
109
  additionalLocalDevDeps = openApiClientLocalDevDeps(agentNameClassName);
107
110
  // HTTP only — the AG-UI branch handles this inside addAgUiReactConnection.
108
111
  // Agent constructs publish their runtime ARN to the 'agentcore' namespace
109
112
  // by default, which isn't exposed to the website; patch them to also
110
- // publish under 'connection' so the browser can read it.
111
- await addAgentRuntimeToConnectionNamespace(tree, {
112
- agentNameKebabCase: kebabCase(agentNameClassName),
113
- agentNameClassName
113
+ // publish under 'connection' so the browser can read it. When routing via
114
+ // a gateway, the gateway publishes its own URL instead.
115
+ if (!options.gatewayRoute) {
116
+ await addAgentRuntimeToConnectionNamespace(tree, {
117
+ agentNameKebabCase: kebabCase(agentNameClassName),
118
+ agentNameClassName
119
+ });
120
+ }
121
+ }
122
+ if (options.gatewayRoute) {
123
+ // The gateway react-connection wires the website's dev target to the
124
+ // local gateway (which proxies to the agent); only the OpenAPI client
125
+ // generation targets are still needed here.
126
+ if (additionalLocalDevDeps.length > 0) {
127
+ const websiteConfig = readProjectConfigurationUnqualified(tree, frontendProjectConfig.name);
128
+ if (websiteConfig.targets?.['dev']) {
129
+ for (const additional of additionalLocalDevDeps){
130
+ addDependencyToTargetIfNotPresent(websiteConfig, 'dev', additional);
131
+ }
132
+ updateProjectConfiguration(tree, websiteConfig.name, websiteConfig);
133
+ }
134
+ }
135
+ } else {
136
+ await addPyAgentTargetToLocalDev(tree, frontendProjectConfig.name, agentProjectConfig.name, {
137
+ agentName,
138
+ agentNameClassName,
139
+ port: agentPort,
140
+ targetComponent,
141
+ additionalDependencyTargets: additionalLocalDevDeps
114
142
  });
115
143
  }
116
- await addPyAgentTargetToLocalDev(tree, frontendProjectConfig.name, agentProjectConfig.name, {
117
- agentName,
118
- agentNameClassName,
119
- port: agentPort,
120
- targetComponent,
121
- additionalDependencyTargets: additionalLocalDevDeps
122
- });
123
144
  // Recorded so the version sync knows this connection's dependencies are ours.
124
145
  addComponentGeneratorMetadata(tree, frontendProjectConfig.name, PY_AGENT_REACT_CONNECTION_GENERATOR_INFO, toProjectRelativePath(frontendProjectConfig, protocol === 'ag-ui' ? joinPathFragments(frontendProjectConfig.sourceRoot, 'hooks', `useAgui${agentNameClassName}`) : joinPathFragments(frontendProjectConfig.sourceRoot, 'components', `${agentNameClassName}Provider`)), agentNameClassName, connectionMetadata);
125
146
  await addGeneratorMetricsIfApplicable(tree, [