@aws/nx-plugin 1.0.0-rc.57 → 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.
- package/LICENSE-THIRD-PARTY +2917 -1295
- package/generators.json +17 -1
- package/migrations.json +36 -26
- package/package.json +13 -13
- package/src/agentcore-gateway/__snapshots__/generator.spec.ts.snap +273 -0
- package/src/agentcore-gateway/agent-connection/generator.d.ts +19 -0
- package/src/agentcore-gateway/agent-connection/generator.js +90 -0
- package/src/agentcore-gateway/agent-connection/generator.js.map +1 -0
- package/src/agentcore-gateway/agent-connection/schema.d.js +6 -0
- package/src/agentcore-gateway/agent-connection/schema.d.js.map +1 -0
- package/src/agentcore-gateway/agent-connection/schema.d.ts +13 -0
- package/src/agentcore-gateway/agent-connection/schema.json +31 -0
- package/src/agentcore-gateway/attach-upstream.d.ts +16 -0
- package/src/agentcore-gateway/attach-upstream.js +32 -11
- package/src/agentcore-gateway/attach-upstream.js.map +1 -1
- package/src/agentcore-gateway/files/project/http/local-dev.ts.template +77 -0
- package/src/agentcore-gateway/generator.d.ts +17 -1
- package/src/agentcore-gateway/generator.js +25 -12
- package/src/agentcore-gateway/generator.js.map +1 -1
- package/src/agentcore-gateway/react-connection/__snapshots__/generator.spec.ts.snap +68 -0
- package/src/agentcore-gateway/react-connection/generator.d.ts +19 -0
- package/src/agentcore-gateway/react-connection/generator.js +119 -0
- package/src/agentcore-gateway/react-connection/generator.js.map +1 -0
- package/src/agentcore-gateway/react-connection/schema.d.js +6 -0
- package/src/agentcore-gateway/react-connection/schema.d.js.map +1 -0
- package/src/agentcore-gateway/react-connection/schema.d.ts +13 -0
- package/src/agentcore-gateway/react-connection/schema.json +31 -0
- package/src/agentcore-gateway/schema.d.js.map +1 -1
- package/src/agentcore-gateway/schema.d.ts +1 -1
- package/src/agentcore-gateway/schema.json +3 -2
- package/src/connection/agent-local-dev.d.ts +16 -0
- package/src/connection/agent-local-dev.js +44 -2
- package/src/connection/agent-local-dev.js.map +1 -1
- package/src/connection/gateway-runtime-config.d.ts +19 -0
- package/src/connection/gateway-runtime-config.js +47 -0
- package/src/connection/gateway-runtime-config.js.map +1 -0
- package/src/connection/generator.js +5 -0
- package/src/connection/generator.js.map +1 -1
- package/src/connection/scaffold-catalog.d.ts +267 -0
- package/src/connection/scaffold-catalog.js +347 -0
- package/src/connection/scaffold-catalog.js.map +1 -0
- package/src/connection/schema-resolver.d.ts +5 -0
- package/src/connection/schema-resolver.js +27 -0
- package/src/connection/schema-resolver.js.map +1 -0
- package/src/connection/supported-connections.d.ts +9 -0
- package/src/connection/supported-connections.js +12 -0
- package/src/connection/supported-connections.js.map +1 -1
- package/src/infra/app/__snapshots__/generator.spec.ts.snap +7 -7
- package/src/internal/test-matrix/generator.js +39 -1
- package/src/internal/test-matrix/generator.js.map +1 -1
- package/src/migrations/latest/gateway-agent-targets/__snapshots__/migration.spec.ts.snap +223 -0
- package/src/migrations/latest/gateway-agent-targets/metadata.json +3 -0
- package/src/migrations/latest/gateway-agent-targets/migration.js +217 -0
- package/src/migrations/latest/gateway-agent-targets/migration.js.map +1 -0
- package/src/migrations/latest/smithy-ssdk-bundle-pins/metadata.json +3 -0
- package/src/migrations/latest/smithy-ssdk-bundle-pins/migration.js +78 -0
- package/src/migrations/latest/smithy-ssdk-bundle-pins/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.50/modernize-function-props-cast/metadata.json +3 -0
- package/src/migrations/v1.0.0-rc.50/modernize-function-props-cast/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.50/restrict-cors-to-custom-domains/metadata.json +3 -0
- package/src/migrations/v1.0.0-rc.50/restrict-cors-to-custom-domains/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.50/terraform-bootstrap-adopt-existing-bucket/metadata.json +3 -0
- package/src/migrations/v1.0.0-rc.50/terraform-bootstrap-adopt-existing-bucket/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.52/user-identity-waf-allow-localhost-callback/metadata.json +3 -0
- package/src/migrations/v1.0.0-rc.52/user-identity-waf-allow-localhost-callback/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.54/order-access-log-delivery-after-bucket-policy/metadata.json +3 -0
- package/src/migrations/v1.0.0-rc.54/order-access-log-delivery-after-bucket-policy/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.55/backfill-generator-metadata/metadata.json +3 -0
- package/src/migrations/v1.0.0-rc.55/backfill-generator-metadata/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.56/dynamodb-local-remove-optimize-flag/metadata.json +3 -0
- package/src/migrations/v1.0.0-rc.56/dynamodb-local-remove-optimize-flag/migration.d.ts +6 -0
- package/src/migrations/v1.0.0-rc.56/dynamodb-local-remove-optimize-flag/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.57/ts-agent-session-management-support/metadata.json +3 -0
- package/src/migrations/v1.0.0-rc.57/ts-agent-session-management-support/migration.d.ts +6 -0
- package/src/migrations/v1.0.0-rc.57/ts-agent-session-management-support/migration.js.map +1 -0
- package/src/preset/__snapshots__/generator.spec.ts.snap +5 -5
- package/src/py/agent/__snapshots__/generator.constructs.spec.ts.snap +10 -8
- package/src/py/agent/__snapshots__/generator.frameworks.spec.ts.snap +8 -8
- package/src/py/agent/__snapshots__/generator.protocols.spec.ts.snap +2 -2
- package/src/py/agent/a2a-connection/generator.d.ts +1 -1
- package/src/py/agent/gateway-connection/generator.d.ts +1 -1
- package/src/py/agent/mcp-connection/generator.d.ts +1 -1
- package/src/py/agent/react-connection/generator.d.ts +4 -1
- package/src/py/agent/react-connection/generator.js +35 -14
- package/src/py/agent/react-connection/generator.js.map +1 -1
- package/src/py/agent/schema.json +1 -0
- package/src/py/dynamodb/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/py/dynamodb/schema.json +1 -0
- package/src/py/fast-api/__snapshots__/generator.terraform.spec.ts.snap +12 -12
- package/src/py/fast-api/generator.d.ts +5 -0
- package/src/py/fast-api/generator.js +3 -2
- package/src/py/fast-api/generator.js.map +1 -1
- package/src/py/fast-api/schema.json +1 -0
- package/src/py/lambda-function/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/py/mcp-server/__snapshots__/generator.spec.ts.snap +5 -5
- package/src/py/mcp-server/schema.json +1 -0
- package/src/py/rdb/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/py/rdb/schema.json +1 -0
- package/src/smithy/project/__snapshots__/generator.spec.ts.snap +4 -4
- package/src/smithy/project/files/service/build.Dockerfile.template +2 -2
- package/src/smithy/project/generator.d.ts +25 -0
- package/src/smithy/project/generator.js +24 -3
- package/src/smithy/project/generator.js.map +1 -1
- package/src/smithy/ts/api/__snapshots__/generator.spec.ts.snap +7 -7
- package/src/smithy/ts/api/generator.d.ts +6 -1
- package/src/smithy/ts/api/generator.js +3 -2
- package/src/smithy/ts/api/generator.js.map +1 -1
- package/src/smithy/ts/api/schema.json +1 -0
- package/src/trpc/backend/__snapshots__/generator.spec.ts.snap +12 -12
- package/src/trpc/backend/generator.d.ts +6 -1
- package/src/trpc/backend/generator.js +3 -2
- package/src/trpc/backend/generator.js.map +1 -1
- package/src/trpc/backend/schema.json +1 -0
- package/src/ts/agent/__snapshots__/generator.spec.ts.snap +9 -5
- package/src/ts/agent/generator.d.ts +32 -1
- package/src/ts/agent/generator.js +7 -4
- package/src/ts/agent/generator.js.map +1 -1
- package/src/ts/agent/react-connection/generator.d.ts +16 -1
- package/src/ts/agent/react-connection/generator.js +21 -8
- package/src/ts/agent/react-connection/generator.js.map +1 -1
- package/src/ts/agent/schema.json +1 -0
- package/src/ts/dcr-proxy/__snapshots__/generator.spec.ts.snap +1 -1
- package/src/ts/dynamodb/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/ts/dynamodb/schema.json +1 -0
- package/src/ts/lambda-function/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/ts/mcp-server/generator.d.ts +32 -1
- package/src/ts/mcp-server/generator.js +7 -4
- package/src/ts/mcp-server/generator.js.map +1 -1
- package/src/ts/mcp-server/schema.json +1 -0
- package/src/ts/nx-migration/generator.js +40 -27
- package/src/ts/nx-migration/generator.js.map +1 -1
- package/src/ts/rdb/__snapshots__/generator.spec.ts.snap +6 -6
- package/src/ts/rdb/generator.d.ts +8 -0
- package/src/ts/rdb/generator.js +3 -2
- package/src/ts/rdb/generator.js.map +1 -1
- package/src/ts/rdb/schema.json +1 -0
- package/src/ts/react-website/agui/files/common/src/hooks/useAgui__agentNameClassName__.tsx.template +16 -0
- package/src/ts/react-website/agui/generator.d.ts +11 -0
- package/src/ts/react-website/agui/generator.js +11 -7
- package/src/ts/react-website/agui/generator.js.map +1 -1
- package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +61 -45
- package/src/ts/react-website/app/generator.d.ts +6 -1
- package/src/ts/react-website/app/generator.js +3 -2
- package/src/ts/react-website/app/generator.js.map +1 -1
- package/src/ts/react-website/app/schema.json +1 -0
- package/src/ts/react-website/cognito-auth/__snapshots__/generator.terraform.spec.ts.snap +2 -2
- package/src/ts/react-website/cognito-auth/generator.d.ts +6 -1
- package/src/ts/react-website/cognito-auth/generator.js +3 -2
- package/src/ts/react-website/cognito-auth/generator.js.map +1 -1
- package/src/utils/agent-core-constructs/agent-core-constructs.d.ts +23 -0
- package/src/utils/agent-core-constructs/agent-core-constructs.js +24 -1
- package/src/utils/agent-core-constructs/agent-core-constructs.js.map +1 -1
- package/src/utils/agent-core-constructs/files/cdk/app/agent-core/__nameKebabCase__/__nameKebabCase__.ts.template +3 -0
- package/src/utils/agent-core-constructs/files/cdk/app/agentcore-gateway/__nameKebabCase__/__nameKebabCase__.ts.template +6 -4
- package/src/utils/agent-core-constructs/files/cdk/core/agentcore-gateway/agentcore-gateway.ts.template +119 -3
- package/src/utils/agent-core-constructs/files/terraform/app/agentcore-gateway/__nameKebabCase__/__nameKebabCase__.tf.template +17 -0
- package/src/utils/api-constructs/api-constructs.d.ts +9 -0
- package/src/utils/api-constructs/api-constructs.js +11 -1
- package/src/utils/api-constructs/api-constructs.js.map +1 -1
- package/src/utils/config/utils.d.ts +5 -0
- package/src/utils/config/utils.js +7 -1
- package/src/utils/config/utils.js.map +1 -1
- package/src/utils/connection/open-api/files/components/__apiNameClassName__Provider.tsx.template +13 -2
- package/src/utils/connection/open-api/react.d.ts +10 -1
- package/src/utils/connection/open-api/react.js +3 -2
- package/src/utils/connection/open-api/react.js.map +1 -1
- package/src/utils/docker.d.ts +27 -2
- package/src/utils/docker.js +31 -2
- package/src/utils/docker.js.map +1 -1
- package/src/utils/identity-constructs/identity-constructs.d.ts +10 -0
- package/src/utils/identity-constructs/identity-constructs.js +11 -1
- package/src/utils/identity-constructs/identity-constructs.js.map +1 -1
- package/src/utils/migration-manifest.d.ts +58 -0
- package/src/utils/migration-manifest.js +76 -0
- package/src/utils/migration-manifest.js.map +1 -0
- package/src/utils/migration-versions.d.ts +2 -0
- package/src/utils/migration-versions.js.map +1 -1
- package/src/utils/shared-constructs-constants.d.ts +6 -0
- package/src/utils/shared-constructs-constants.js +5 -0
- package/src/utils/shared-constructs-constants.js.map +1 -1
- package/src/utils/version-upgrade-migration/owned-dependencies.d.ts +26 -0
- package/src/utils/version-upgrade-migration/owned-dependencies.js +52 -4
- package/src/utils/version-upgrade-migration/owned-dependencies.js.map +1 -1
- package/src/utils/version-upgrade-migration/register.d.ts +9 -3
- package/src/utils/version-upgrade-migration/register.js +18 -14
- package/src/utils/version-upgrade-migration/register.js.map +1 -1
- package/src/utils/version-upgrade-migration/sync-embedded-versions.d.ts +26 -0
- package/src/utils/version-upgrade-migration/sync-embedded-versions.js +304 -0
- package/src/utils/version-upgrade-migration/sync-embedded-versions.js.map +1 -0
- package/src/utils/version-upgrade-migration/sync-vended-versions.js +14 -0
- package/src/utils/version-upgrade-migration/sync-vended-versions.js.map +1 -1
- package/src/utils/versions.d.ts +90 -77
- package/src/utils/versions.js +86 -75
- package/src/utils/versions.js.map +1 -1
- package/src/utils/website-constructs/website-constructs.d.ts +11 -0
- package/src/utils/website-constructs/website-constructs.js +12 -1
- package/src/utils/website-constructs/website-constructs.js.map +1 -1
- package/src/migrations/latest/backfill-generator-metadata/migration.js.map +0 -1
- package/src/migrations/latest/dynamodb-local-remove-optimize-flag/migration.js.map +0 -1
- package/src/migrations/latest/modernize-function-props-cast/migration.js.map +0 -1
- package/src/migrations/latest/order-access-log-delivery-after-bucket-policy/migration.js.map +0 -1
- package/src/migrations/latest/restrict-cors-to-custom-domains/migration.js.map +0 -1
- package/src/migrations/latest/terraform-bootstrap-adopt-existing-bucket/migration.js.map +0 -1
- package/src/migrations/latest/ts-agent-session-management-support/migration.js.map +0 -1
- package/src/migrations/latest/user-identity-waf-allow-localhost-callback/migration.js.map +0 -1
- /package/src/agentcore-gateway/files/project/{local-dev.ts.template → mcp/local-dev.ts.template} +0 -0
- /package/src/migrations/latest/{dynamodb-local-remove-optimize-flag → gateway-agent-targets}/migration.d.ts +0 -0
- /package/src/migrations/latest/{modernize-function-props-cast → smithy-ssdk-bundle-pins}/migration.d.ts +0 -0
- /package/src/migrations/{latest/restrict-cors-to-custom-domains → v1.0.0-rc.50/modernize-function-props-cast}/migration.d.ts +0 -0
- /package/src/migrations/{latest → v1.0.0-rc.50}/modernize-function-props-cast/migration.js +0 -0
- /package/src/migrations/{latest/terraform-bootstrap-adopt-existing-bucket → v1.0.0-rc.50/restrict-cors-to-custom-domains}/migration.d.ts +0 -0
- /package/src/migrations/{latest → v1.0.0-rc.50}/restrict-cors-to-custom-domains/migration.js +0 -0
- /package/src/migrations/{latest/ts-agent-session-management-support → v1.0.0-rc.50/terraform-bootstrap-adopt-existing-bucket}/migration.d.ts +0 -0
- /package/src/migrations/{latest → v1.0.0-rc.50}/terraform-bootstrap-adopt-existing-bucket/migration.js +0 -0
- /package/src/migrations/{latest/order-access-log-delivery-after-bucket-policy → v1.0.0-rc.52/user-identity-waf-allow-localhost-callback}/migration.d.ts +0 -0
- /package/src/migrations/{latest → v1.0.0-rc.52}/user-identity-waf-allow-localhost-callback/migration.js +0 -0
- /package/src/migrations/{latest/user-identity-waf-allow-localhost-callback → v1.0.0-rc.54/order-access-log-delivery-after-bucket-policy}/migration.d.ts +0 -0
- /package/src/migrations/{latest → v1.0.0-rc.54}/order-access-log-delivery-after-bucket-policy/migration.js +0 -0
- /package/src/migrations/{latest → v1.0.0-rc.55}/backfill-generator-metadata/migration.d.ts +0 -0
- /package/src/migrations/{latest → v1.0.0-rc.55}/backfill-generator-metadata/migration.js +0 -0
- /package/src/migrations/{latest → v1.0.0-rc.56}/dynamodb-local-remove-optimize-flag/migration.js +0 -0
- /package/src/migrations/{latest → v1.0.0-rc.57}/ts-agent-session-management-support/migration.js +0 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/schema",
|
|
3
|
+
"$id": "agentcore-gateway#agent-connection",
|
|
4
|
+
"title": "agentcore-gateway#agent-connection",
|
|
5
|
+
"description": "Connect an AgentCore Gateway to an agent, adding the agent as a gateway target",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"sourceProject": {
|
|
9
|
+
"type": "string",
|
|
10
|
+
"description": "The gateway project"
|
|
11
|
+
},
|
|
12
|
+
"targetProject": {
|
|
13
|
+
"type": "string",
|
|
14
|
+
"description": "The agent project"
|
|
15
|
+
},
|
|
16
|
+
"sourceComponent": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"description": "The gateway component in the source project"
|
|
19
|
+
},
|
|
20
|
+
"targetComponent": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"description": "The agent component in the target project"
|
|
23
|
+
},
|
|
24
|
+
"preferInstallDependencies": {
|
|
25
|
+
"type": "boolean",
|
|
26
|
+
"description": "Whether to prefer installing dependencies after the generator runs. Set to false to defer installing when batching multiple generators (an install still runs if needed so subsequent generators can compute the Nx project graph); install once at the end.",
|
|
27
|
+
"default": true
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"required": ["sourceProject", "targetProject"]
|
|
31
|
+
}
|
|
@@ -31,3 +31,19 @@ export interface LocalGatewayUpstream {
|
|
|
31
31
|
* aggregates its tools.
|
|
32
32
|
*/
|
|
33
33
|
export declare const attachUpstreamToLocalGateway: (tree: Tree, gatewayProject: ProjectConfiguration, gatewayDevTargetName: string, upstream: LocalGatewayUpstream) => Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Attach an upstream agent to an http gateway's local gateway.
|
|
36
|
+
*
|
|
37
|
+
* Chains the gateway's dev target onto the agent's dev target, and registers
|
|
38
|
+
* the agent in the gateway's local-dev.ts so the local gateway proxies
|
|
39
|
+
* `/<targetName>/...` to it.
|
|
40
|
+
*/
|
|
41
|
+
export declare const attachAgentToLocalGateway: (tree: Tree, gatewayProject: ProjectConfiguration, gatewayDevTargetName: string, upstream: LocalGatewayUpstream & {
|
|
42
|
+
/**
|
|
43
|
+
* Whether to strip the `/invocations` path prefix when proxying. The
|
|
44
|
+
* deployed gateway maps an A2A target's `/invocations/...` paths onto the
|
|
45
|
+
* agent container's root, so the local proxy does the same; HTTP and
|
|
46
|
+
* AG-UI agents serve `/invocations` themselves.
|
|
47
|
+
*/
|
|
48
|
+
stripInvocations: boolean;
|
|
49
|
+
}) => Promise<void>;
|
|
@@ -12,17 +12,8 @@ import { addDependencyToTargetIfNotPresent } from "../utils/nx.js";
|
|
|
12
12
|
* registers the upstream in the gateway's local-dev.ts so the local gateway
|
|
13
13
|
* aggregates its tools.
|
|
14
14
|
*/ export const attachUpstreamToLocalGateway = async (tree, gatewayProject, gatewayDevTargetName, upstream)=>{
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
addDependencyToTargetIfNotPresent(gatewayProject, gatewayDevTargetName, {
|
|
18
|
-
projects: [
|
|
19
|
-
upstream.upstreamProjectName
|
|
20
|
-
],
|
|
21
|
-
target: upstream.upstreamDevTargetName
|
|
22
|
-
});
|
|
23
|
-
updateProjectConfiguration(tree, gatewayProject.name, gatewayProject);
|
|
24
|
-
}
|
|
25
|
-
// 2. Register the upstream in the gateway's local local-dev.ts
|
|
15
|
+
chainGatewayDevTarget(tree, gatewayProject, gatewayDevTargetName, upstream);
|
|
16
|
+
// Register the upstream in the gateway's local local-dev.ts
|
|
26
17
|
const serveTsPath = joinPathFragments(gatewayProject.root, 'local-dev.ts');
|
|
27
18
|
if (tree.exists(serveTsPath)) {
|
|
28
19
|
const entry = `{ name: '${upstream.targetName}', url: 'http://localhost:${upstream.port}/mcp' }`;
|
|
@@ -34,5 +25,35 @@ import { addDependencyToTargetIfNotPresent } from "../utils/nx.js";
|
|
|
34
25
|
}`);
|
|
35
26
|
}
|
|
36
27
|
};
|
|
28
|
+
/**
|
|
29
|
+
* Attach an upstream agent to an http gateway's local gateway.
|
|
30
|
+
*
|
|
31
|
+
* Chains the gateway's dev target onto the agent's dev target, and registers
|
|
32
|
+
* the agent in the gateway's local-dev.ts so the local gateway proxies
|
|
33
|
+
* `/<targetName>/...` to it.
|
|
34
|
+
*/ export const attachAgentToLocalGateway = async (tree, gatewayProject, gatewayDevTargetName, upstream)=>{
|
|
35
|
+
chainGatewayDevTarget(tree, gatewayProject, gatewayDevTargetName, upstream);
|
|
36
|
+
const serveTsPath = joinPathFragments(gatewayProject.root, 'local-dev.ts');
|
|
37
|
+
if (tree.exists(serveTsPath)) {
|
|
38
|
+
const entry = `{ name: '${upstream.targetName}', url: 'http://localhost:${upstream.port}', stripInvocations: ${upstream.stripInvocations} }`;
|
|
39
|
+
await applyGritQL(tree, serveTsPath, `or {
|
|
40
|
+
\`const ATTACHED_AGENTS: AttachedAgent[] = []\` => \`const ATTACHED_AGENTS: AttachedAgent[] = [${entry}]\`,
|
|
41
|
+
\`const ATTACHED_AGENTS: AttachedAgent[] = [$items]\` => \`const ATTACHED_AGENTS: AttachedAgent[] = [${entry}, $items]\` where {
|
|
42
|
+
$items <: not contains \`'${upstream.targetName}'\`
|
|
43
|
+
}
|
|
44
|
+
}`);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
/** Chain the gateway's dev target onto the upstream's dev target. */ const chainGatewayDevTarget = (tree, gatewayProject, gatewayDevTargetName, upstream)=>{
|
|
48
|
+
if (gatewayProject.targets?.[gatewayDevTargetName]) {
|
|
49
|
+
addDependencyToTargetIfNotPresent(gatewayProject, gatewayDevTargetName, {
|
|
50
|
+
projects: [
|
|
51
|
+
upstream.upstreamProjectName
|
|
52
|
+
],
|
|
53
|
+
target: upstream.upstreamDevTargetName
|
|
54
|
+
});
|
|
55
|
+
updateProjectConfiguration(tree, gatewayProject.name, gatewayProject);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
37
58
|
|
|
38
59
|
//# sourceMappingURL=attach-upstream.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../packages/nx-plugin/src/agentcore-gateway/attach-upstream.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n joinPathFragments,\n type ProjectConfiguration,\n type Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport { applyGritQL } from '../utils/ast';\nimport { addDependencyToTargetIfNotPresent } from '../utils/nx';\n\nexport interface LocalGatewayUpstream {\n /**\n * Gateway target name for the upstream — prefixes its tools as\n * `<targetName>___<toolName>` both locally and deployed.\n */\n targetName: string;\n /**\n * Local port the upstream MCP endpoint listens on.\n */\n port: number;\n /**\n * Project providing the upstream's dev target.\n */\n upstreamProjectName: string;\n /**\n * Name of the upstream's dev target.\n */\n upstreamDevTargetName: string;\n}\n\n/**\n * Attach an upstream MCP endpoint (an MCP server or another gateway's local\n * gateway) to a gateway's local gateway.\n *\n * Chains the gateway's dev target onto the upstream's dev target, and\n * registers the upstream in the gateway's local-dev.ts so the local gateway\n * aggregates its tools.\n */\nexport const attachUpstreamToLocalGateway = async (\n tree: Tree,\n gatewayProject: ProjectConfiguration,\n gatewayDevTargetName: string,\n upstream: LocalGatewayUpstream,\n): Promise<void> => {\n //
|
|
1
|
+
{"version":3,"sources":["../../../../../packages/nx-plugin/src/agentcore-gateway/attach-upstream.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n joinPathFragments,\n type ProjectConfiguration,\n type Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport { applyGritQL } from '../utils/ast';\nimport { addDependencyToTargetIfNotPresent } from '../utils/nx';\n\nexport interface LocalGatewayUpstream {\n /**\n * Gateway target name for the upstream — prefixes its tools as\n * `<targetName>___<toolName>` both locally and deployed.\n */\n targetName: string;\n /**\n * Local port the upstream MCP endpoint listens on.\n */\n port: number;\n /**\n * Project providing the upstream's dev target.\n */\n upstreamProjectName: string;\n /**\n * Name of the upstream's dev target.\n */\n upstreamDevTargetName: string;\n}\n\n/**\n * Attach an upstream MCP endpoint (an MCP server or another gateway's local\n * gateway) to a gateway's local gateway.\n *\n * Chains the gateway's dev target onto the upstream's dev target, and\n * registers the upstream in the gateway's local-dev.ts so the local gateway\n * aggregates its tools.\n */\nexport const attachUpstreamToLocalGateway = async (\n tree: Tree,\n gatewayProject: ProjectConfiguration,\n gatewayDevTargetName: string,\n upstream: LocalGatewayUpstream,\n): Promise<void> => {\n chainGatewayDevTarget(tree, gatewayProject, gatewayDevTargetName, upstream);\n\n // Register the upstream in the gateway's local local-dev.ts\n const serveTsPath = joinPathFragments(gatewayProject.root, 'local-dev.ts');\n if (tree.exists(serveTsPath)) {\n const entry = `{ name: '${upstream.targetName}', url: 'http://localhost:${upstream.port}/mcp' }`;\n await applyGritQL(\n tree,\n serveTsPath,\n `or {\n \\`const ATTACHED_MCP_SERVERS: AttachedMcpServer[] = []\\` => \\`const ATTACHED_MCP_SERVERS: AttachedMcpServer[] = [${entry}]\\`,\n \\`const ATTACHED_MCP_SERVERS: AttachedMcpServer[] = [$items]\\` => \\`const ATTACHED_MCP_SERVERS: AttachedMcpServer[] = [${entry}, $items]\\` where {\n $items <: not contains \\`'${upstream.targetName}'\\`\n }\n}`,\n );\n }\n};\n\n/**\n * Attach an upstream agent to an http gateway's local gateway.\n *\n * Chains the gateway's dev target onto the agent's dev target, and registers\n * the agent in the gateway's local-dev.ts so the local gateway proxies\n * `/<targetName>/...` to it.\n */\nexport const attachAgentToLocalGateway = async (\n tree: Tree,\n gatewayProject: ProjectConfiguration,\n gatewayDevTargetName: string,\n upstream: LocalGatewayUpstream & {\n /**\n * Whether to strip the `/invocations` path prefix when proxying. The\n * deployed gateway maps an A2A target's `/invocations/...` paths onto the\n * agent container's root, so the local proxy does the same; HTTP and\n * AG-UI agents serve `/invocations` themselves.\n */\n stripInvocations: boolean;\n },\n): Promise<void> => {\n chainGatewayDevTarget(tree, gatewayProject, gatewayDevTargetName, upstream);\n\n const serveTsPath = joinPathFragments(gatewayProject.root, 'local-dev.ts');\n if (tree.exists(serveTsPath)) {\n const entry = `{ name: '${upstream.targetName}', url: 'http://localhost:${upstream.port}', stripInvocations: ${upstream.stripInvocations} }`;\n await applyGritQL(\n tree,\n serveTsPath,\n `or {\n \\`const ATTACHED_AGENTS: AttachedAgent[] = []\\` => \\`const ATTACHED_AGENTS: AttachedAgent[] = [${entry}]\\`,\n \\`const ATTACHED_AGENTS: AttachedAgent[] = [$items]\\` => \\`const ATTACHED_AGENTS: AttachedAgent[] = [${entry}, $items]\\` where {\n $items <: not contains \\`'${upstream.targetName}'\\`\n }\n}`,\n );\n }\n};\n\n/** Chain the gateway's dev target onto the upstream's dev target. */\nconst chainGatewayDevTarget = (\n tree: Tree,\n gatewayProject: ProjectConfiguration,\n gatewayDevTargetName: string,\n upstream: LocalGatewayUpstream,\n): void => {\n if (gatewayProject.targets?.[gatewayDevTargetName]) {\n addDependencyToTargetIfNotPresent(gatewayProject, gatewayDevTargetName, {\n projects: [upstream.upstreamProjectName],\n target: upstream.upstreamDevTargetName,\n });\n updateProjectConfiguration(tree, gatewayProject.name, gatewayProject);\n }\n};\n"],"names":["joinPathFragments","updateProjectConfiguration","applyGritQL","addDependencyToTargetIfNotPresent","attachUpstreamToLocalGateway","tree","gatewayProject","gatewayDevTargetName","upstream","chainGatewayDevTarget","serveTsPath","root","exists","entry","targetName","port","attachAgentToLocalGateway","stripInvocations","targets","projects","upstreamProjectName","target","upstreamDevTargetName","name"],"mappings":"AAAA;;;CAGC,GACD,SACEA,iBAAiB,EAGjBC,0BAA0B,QACrB,aAAa;AACpB,SAASC,WAAW,QAAQ,kBAAe;AAC3C,SAASC,iCAAiC,QAAQ,iBAAc;AAsBhE;;;;;;;CAOC,GACD,OAAO,MAAMC,+BAA+B,OAC1CC,MACAC,gBACAC,sBACAC;IAEAC,sBAAsBJ,MAAMC,gBAAgBC,sBAAsBC;IAElE,4DAA4D;IAC5D,MAAME,cAAcV,kBAAkBM,eAAeK,IAAI,EAAE;IAC3D,IAAIN,KAAKO,MAAM,CAACF,cAAc;QAC5B,MAAMG,QAAQ,CAAC,SAAS,EAAEL,SAASM,UAAU,CAAC,0BAA0B,EAAEN,SAASO,IAAI,CAAC,OAAO,CAAC;QAChG,MAAMb,YACJG,MACAK,aACA,CAAC;mHAC4G,EAAEG,MAAM;yHACF,EAAEA,MAAM;8BACnG,EAAEL,SAASM,UAAU,CAAC;;CAEnD,CAAC;IAEA;AACF,EAAE;AAEF;;;;;;CAMC,GACD,OAAO,MAAME,4BAA4B,OACvCX,MACAC,gBACAC,sBACAC;IAUAC,sBAAsBJ,MAAMC,gBAAgBC,sBAAsBC;IAElE,MAAME,cAAcV,kBAAkBM,eAAeK,IAAI,EAAE;IAC3D,IAAIN,KAAKO,MAAM,CAACF,cAAc;QAC5B,MAAMG,QAAQ,CAAC,SAAS,EAAEL,SAASM,UAAU,CAAC,0BAA0B,EAAEN,SAASO,IAAI,CAAC,qBAAqB,EAAEP,SAASS,gBAAgB,CAAC,EAAE,CAAC;QAC5I,MAAMf,YACJG,MACAK,aACA,CAAC;iGAC0F,EAAEG,MAAM;uGACF,EAAEA,MAAM;8BACjF,EAAEL,SAASM,UAAU,CAAC;;CAEnD,CAAC;IAEA;AACF,EAAE;AAEF,mEAAmE,GACnE,MAAML,wBAAwB,CAC5BJ,MACAC,gBACAC,sBACAC;IAEA,IAAIF,eAAeY,OAAO,EAAE,CAACX,qBAAqB,EAAE;QAClDJ,kCAAkCG,gBAAgBC,sBAAsB;YACtEY,UAAU;gBAACX,SAASY,mBAAmB;aAAC;YACxCC,QAAQb,SAASc,qBAAqB;QACxC;QACArB,2BAA2BI,MAAMC,eAAeiB,IAAI,EAAEjB;IACxD;AACF"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import { Readable } from 'node:stream';
|
|
3
|
+
|
|
4
|
+
const PORT = parseInt(process.env.PORT || '<%- port %>');
|
|
5
|
+
|
|
6
|
+
interface AttachedAgent {
|
|
7
|
+
name: string;
|
|
8
|
+
url: string;
|
|
9
|
+
/**
|
|
10
|
+
* Whether to strip the `/invocations` path prefix when proxying. The
|
|
11
|
+
* deployed gateway maps an A2A target's `/invocations/...` paths onto the
|
|
12
|
+
* agent container's root; HTTP and AG-UI agents serve `/invocations`
|
|
13
|
+
* themselves.
|
|
14
|
+
*/
|
|
15
|
+
stripInvocations: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Upstream agent endpoints attached to this gateway, maintained by the
|
|
19
|
+
// `agentcore-gateway#agent-connection` generator.
|
|
20
|
+
const ATTACHED_AGENTS: AttachedAgent[] = [<% attachedAgents.forEach((a) => { %>
|
|
21
|
+
{ name: '<%- a.name %>', url: 'http://localhost:<%- a.port %>', stripInvocations: <%- a.stripInvocations %> },<% }); %>
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Local gateway for <%- nameClassName %>: proxies `/<targetName>/<path>` to
|
|
26
|
+
* the attached agent's local server, matching the deployed AgentCore
|
|
27
|
+
* Gateway's path-based routing for agent runtime targets.
|
|
28
|
+
*/
|
|
29
|
+
const app = express();
|
|
30
|
+
|
|
31
|
+
app.use(async (req, res) => {
|
|
32
|
+
const [, targetName, ...rest] = req.url.split('/');
|
|
33
|
+
const upstream = ATTACHED_AGENTS.find((a) => a.name === targetName);
|
|
34
|
+
if (!upstream) {
|
|
35
|
+
res.status(404).json({ message: `Unknown gateway target: ${targetName}` });
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const upstreamPath = upstream.stripInvocations
|
|
39
|
+
? rest.join('/').replace(/^invocations\/?/, '')
|
|
40
|
+
: rest.join('/');
|
|
41
|
+
try {
|
|
42
|
+
const response = await fetch(`${upstream.url}/${upstreamPath}`, {
|
|
43
|
+
method: req.method,
|
|
44
|
+
headers: Object.fromEntries(
|
|
45
|
+
Object.entries(req.headers).filter(
|
|
46
|
+
([key, value]) => typeof value === 'string' && key !== 'host',
|
|
47
|
+
) as [string, string][],
|
|
48
|
+
),
|
|
49
|
+
body: ['GET', 'HEAD'].includes(req.method)
|
|
50
|
+
? undefined
|
|
51
|
+
: Readable.toWeb(req),
|
|
52
|
+
// Node's fetch requires half-duplex for streamed request bodies.
|
|
53
|
+
duplex: 'half',
|
|
54
|
+
} as RequestInit);
|
|
55
|
+
res.status(response.status);
|
|
56
|
+
response.headers.forEach((value, key) => {
|
|
57
|
+
// The upstream body arrives decoded, so its encoding headers would be incorrect.
|
|
58
|
+
if (!['content-encoding', 'content-length'].includes(key)) {
|
|
59
|
+
res.setHeader(key, value);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
if (response.body) {
|
|
63
|
+
Readable.fromWeb(response.body as any).pipe(res);
|
|
64
|
+
} else {
|
|
65
|
+
res.end();
|
|
66
|
+
}
|
|
67
|
+
} catch (error) {
|
|
68
|
+
console.error(`Error proxying to ${upstream.name}:`, error);
|
|
69
|
+
if (!res.headersSent) {
|
|
70
|
+
res.status(502).json({ message: 'Bad gateway' });
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
app.listen(PORT, () => {
|
|
76
|
+
console.log(`<%- nameKebabCase %>: local gateway listening on port ${PORT}`);
|
|
77
|
+
});
|
|
@@ -8,6 +8,7 @@ import type { IacMetadata } from '../utils/shared-constructs-constants';
|
|
|
8
8
|
import type { AgentcoreGatewayGeneratorSchema } from './schema';
|
|
9
9
|
export declare const DEPENDENCIES: import("../utils/declared-dependencies").DependencyDeclaration<readonly [{
|
|
10
10
|
readonly name: "@modelcontextprotocol/sdk";
|
|
11
|
+
readonly when: (m: AgentCoreGatewayMetadata) => boolean;
|
|
11
12
|
}, {
|
|
12
13
|
readonly name: "express";
|
|
13
14
|
}, {
|
|
@@ -52,7 +53,22 @@ export declare const DEPENDENCIES: import("../utils/declared-dependencies").Depe
|
|
|
52
53
|
readonly name: "@types/node";
|
|
53
54
|
} & {
|
|
54
55
|
versionOnly: true;
|
|
55
|
-
}], readonly
|
|
56
|
+
}], readonly [{
|
|
57
|
+
readonly name: "boto3";
|
|
58
|
+
readonly when: (m: IacMetadata) => boolean;
|
|
59
|
+
} & {
|
|
60
|
+
versionOnly: true;
|
|
61
|
+
}, {
|
|
62
|
+
readonly name: "httpx";
|
|
63
|
+
readonly when: (m: IacMetadata) => boolean;
|
|
64
|
+
} & {
|
|
65
|
+
versionOnly: true;
|
|
66
|
+
}, {
|
|
67
|
+
readonly name: "mcp";
|
|
68
|
+
readonly when: (m: IacMetadata) => boolean;
|
|
69
|
+
} & {
|
|
70
|
+
versionOnly: true;
|
|
71
|
+
}]>;
|
|
56
72
|
export declare const AGENTCORE_GATEWAY_GENERATOR_INFO: NxGeneratorInfo;
|
|
57
73
|
export declare const agentcoreGatewayGenerator: (tree: Tree, options: AgentcoreGatewayGeneratorSchema) => Promise<GeneratorCallback>;
|
|
58
74
|
/**
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
-
*/ import { addProjectConfiguration, generateFiles, joinPathFragments, OverwriteStrategy, updateProjectConfiguration } from "@nx/devkit";
|
|
4
|
+
*/ import { addProjectConfiguration, generateFiles, joinPathFragments, logger, OverwriteStrategy, updateProjectConfiguration } from "@nx/devkit";
|
|
5
5
|
import { addTsDependencies } from "../utils/add-dependencies.js";
|
|
6
|
-
import { AGENT_CORE_CONSTRUCTS_DEPENDENCIES, addAgentCoreGatewayInfra } from "../utils/agent-core-constructs/agent-core-constructs.js";
|
|
6
|
+
import { AGENT_CORE_CONSTRUCTS_DEPENDENCIES, AGENT_CORE_CONSTRUCTS_PY_DEPENDENCIES, addAgentCoreGatewayInfra } from "../utils/agent-core-constructs/agent-core-constructs.js";
|
|
7
7
|
import { declareDependencies, ownedElsewhere } from "../utils/declared-dependencies.js";
|
|
8
8
|
import { formatFilesInSubtree } from "../utils/format.js";
|
|
9
9
|
import { resolveIac } from "../utils/iac.js";
|
|
@@ -15,12 +15,14 @@ import { addGeneratorMetadata, getGeneratorInfo, projectExists, readProjectConfi
|
|
|
15
15
|
import { assignPort } from "../utils/port.js";
|
|
16
16
|
import { ensureProjectPackageJson } from "../utils/project-package-json.js";
|
|
17
17
|
import { SHARED_CONSTRUCTS_DEPENDENCIES, sharedConstructsGenerator } from "../utils/shared-constructs.js";
|
|
18
|
-
// The gateway's local-dev server and Cedar policy rendering need these
|
|
19
|
-
// the
|
|
18
|
+
// The gateway's local-dev server and Cedar policy rendering need these
|
|
19
|
+
// whatever the auth; only the MCP SDK is protocol-specific (the http local
|
|
20
|
+
// gateway is a plain proxy).
|
|
20
21
|
export const DEPENDENCIES = declareDependencies()({
|
|
21
22
|
ts: [
|
|
22
23
|
{
|
|
23
|
-
name: '@modelcontextprotocol/sdk'
|
|
24
|
+
name: '@modelcontextprotocol/sdk',
|
|
25
|
+
when: (m)=>m.protocol === 'mcp'
|
|
24
26
|
},
|
|
25
27
|
{
|
|
26
28
|
name: 'express'
|
|
@@ -46,7 +48,8 @@ export const DEPENDENCIES = declareDependencies()({
|
|
|
46
48
|
},
|
|
47
49
|
...ownedElsewhere(AGENT_CORE_CONSTRUCTS_DEPENDENCIES),
|
|
48
50
|
...ownedElsewhere(SHARED_CONSTRUCTS_DEPENDENCIES)
|
|
49
|
-
]
|
|
51
|
+
],
|
|
52
|
+
py: ownedElsewhere(AGENT_CORE_CONSTRUCTS_PY_DEPENDENCIES)
|
|
50
53
|
});
|
|
51
54
|
export const AGENTCORE_GATEWAY_GENERATOR_INFO = getGeneratorInfo(import.meta.filename);
|
|
52
55
|
export const agentcoreGatewayGenerator = async (tree, options)=>{
|
|
@@ -56,15 +59,23 @@ export const agentcoreGatewayGenerator = async (tree, options)=>{
|
|
|
56
59
|
const subDir = options.subDirectory ?? name;
|
|
57
60
|
const projectRoot = joinPathFragments(parentDir, subDir);
|
|
58
61
|
const fullyQualifiedName = `${getNpmScopePrefix(tree)}${name}`;
|
|
59
|
-
// Protocol is
|
|
60
|
-
//
|
|
61
|
-
//
|
|
62
|
+
// Protocol is mcp (aggregate MCP server targets into one MCP endpoint) or
|
|
63
|
+
// http (proxy agent runtime targets via path-based routing). Persisted in
|
|
64
|
+
// metadata so connection generators can validate it.
|
|
62
65
|
const protocol = options.protocol ?? 'mcp';
|
|
63
66
|
// Inbound auth is iam (default) or cognito. Persisted in metadata so
|
|
64
67
|
// connection generators can validate it (agent -> gateway connections
|
|
65
68
|
// require an IAM gateway).
|
|
66
69
|
const auth = options.auth ?? 'iam';
|
|
67
|
-
|
|
70
|
+
// Cedar policies authorize MCP tool actions, which an http gateway has none
|
|
71
|
+
// of — its runtime targets are plain proxied endpoints — so the policy
|
|
72
|
+
// engine only applies to mcp gateways. cedarPolicy defaults to true in the
|
|
73
|
+
// schema, so an http gateway quietly drops it rather than requiring
|
|
74
|
+
// --cedarPolicy=false.
|
|
75
|
+
if (protocol === 'http' && options.cedarPolicy) {
|
|
76
|
+
logger.warn('Cedar policies authorize MCP tool actions, so cedarPolicy is ignored for http-protocol gateways.');
|
|
77
|
+
}
|
|
78
|
+
const cedarPolicy = protocol === 'mcp' && (options.cedarPolicy ?? true);
|
|
68
79
|
const infra = options.infra ?? 'agentcore';
|
|
69
80
|
// local-dev.ts is the local gateway: a continuous MCP aggregator chaining
|
|
70
81
|
// onto attached MCP servers' dev targets (added by the mcp-connection
|
|
@@ -118,11 +129,12 @@ export const agentcoreGatewayGenerator = async (tree, options)=>{
|
|
|
118
129
|
project.targets['dev'] ??= localGatewayTarget(port);
|
|
119
130
|
updateProjectConfiguration(tree, project.name, project);
|
|
120
131
|
// Scaffold the gateway project: local-dev.ts (+ Cedar policies if requested)
|
|
121
|
-
generateFiles(tree, joinPathFragments(import.meta.dirname, 'files', 'project'), projectRoot, {
|
|
132
|
+
generateFiles(tree, joinPathFragments(import.meta.dirname, 'files', 'project', protocol), projectRoot, {
|
|
122
133
|
nameClassName,
|
|
123
134
|
nameKebabCase: name,
|
|
124
135
|
port,
|
|
125
|
-
attachedMcpServers: []
|
|
136
|
+
attachedMcpServers: [],
|
|
137
|
+
attachedAgents: []
|
|
126
138
|
}, {
|
|
127
139
|
overwriteStrategy: OverwriteStrategy.KeepExisting
|
|
128
140
|
});
|
|
@@ -171,6 +183,7 @@ export const agentcoreGatewayGenerator = async (tree, options)=>{
|
|
|
171
183
|
projectDirectory: projectRoot,
|
|
172
184
|
cedarPolicy,
|
|
173
185
|
auth,
|
|
186
|
+
protocol,
|
|
174
187
|
iac
|
|
175
188
|
}, DEPENDENCIES);
|
|
176
189
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../packages/nx-plugin/src/agentcore-gateway/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n addProjectConfiguration,\n type GeneratorCallback,\n generateFiles,\n joinPathFragments,\n OverwriteStrategy,\n type ProjectConfiguration,\n type Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport { addTsDependencies } from '../utils/add-dependencies';\nimport {\n AGENT_CORE_CONSTRUCTS_DEPENDENCIES,\n addAgentCoreGatewayInfra,\n} from '../utils/agent-core-constructs/agent-core-constructs';\nimport {\n declareDependencies,\n ownedElsewhere,\n} from '../utils/declared-dependencies';\nimport { formatFilesInSubtree } from '../utils/format';\nimport { resolveIac } from '../utils/iac';\nimport { installDependencies } from '../utils/install';\nimport { addGeneratorMetricsIfApplicable } from '../utils/metrics';\nimport { kebabCase, toClassName } from '../utils/names';\nimport { getNpmScopePrefix } from '../utils/npm-scope';\nimport {\n addGeneratorMetadata,\n getGeneratorInfo,\n type NxGeneratorInfo,\n projectExists,\n readProjectConfigurationUnqualified,\n} from '../utils/nx';\nimport { assignPort } from '../utils/port';\nimport { ensureProjectPackageJson } from '../utils/project-package-json';\nimport {\n SHARED_CONSTRUCTS_DEPENDENCIES,\n sharedConstructsGenerator,\n} from '../utils/shared-constructs';\nimport type { IacMetadata } from '../utils/shared-constructs-constants';\nimport type { AgentcoreGatewayGeneratorSchema } from './schema';\n\n// The gateway's local-dev server and Cedar policy rendering need these whatever\n// the protocol or auth, so no entry is conditional.\nexport const DEPENDENCIES = declareDependencies<AgentCoreGatewayMetadata>()({\n ts: [\n { name: '@modelcontextprotocol/sdk' },\n { name: 'express' },\n { name: '@types/express', dev: true },\n // ejs renders the Cedar policy in the shared gateway construct.\n { name: 'ejs', dev: true },\n { name: '@types/ejs', dev: true },\n // local-dev.ts runs via tsx, which is shared tooling.\n { name: 'tsx', dev: true, root: true },\n ...ownedElsewhere(AGENT_CORE_CONSTRUCTS_DEPENDENCIES),\n ...ownedElsewhere(SHARED_CONSTRUCTS_DEPENDENCIES),\n ],\n});\n\nexport const AGENTCORE_GATEWAY_GENERATOR_INFO: NxGeneratorInfo =\n getGeneratorInfo(import.meta.filename);\n\nexport const agentcoreGatewayGenerator = async (\n tree: Tree,\n options: AgentcoreGatewayGeneratorSchema,\n): Promise<GeneratorCallback> => {\n const name = kebabCase(options.name);\n const nameClassName = toClassName(name);\n const parentDir = options.directory ?? 'packages';\n const subDir = options.subDirectory ?? name;\n const projectRoot = joinPathFragments(parentDir, subDir);\n const fullyQualifiedName = `${getNpmScopePrefix(tree)}${name}`;\n\n // Protocol is fixed to mcp — the enum accepts only this value, but we still\n // persist the resolved value in metadata so connection generators can read\n // it uniformly (and future additions are non-breaking).\n const protocol = options.protocol ?? 'mcp';\n // Inbound auth is iam (default) or cognito. Persisted in metadata so\n // connection generators can validate it (agent -> gateway connections\n // require an IAM gateway).\n const auth = options.auth ?? 'iam';\n const cedarPolicy = options.cedarPolicy ?? true;\n const infra = options.infra ?? 'agentcore';\n\n // local-dev.ts is the local gateway: a continuous MCP aggregator chaining\n // onto attached MCP servers' dev targets (added by the mcp-connection\n // generator), so a single `nx dev <gateway>` boots the gateway and every\n // attached MCP server together.\n //\n // `serve` exists for parity with other generators; the deployed Gateway is\n // a managed AWS resource, so `serve`-mode agents talk to it via runtime\n // config and the local gateway sits idle.\n const localGatewayTarget = (port: number) => ({\n executor: 'nx:run-commands' as const,\n continuous: true,\n options: {\n command: 'tsx local-dev.ts',\n cwd: '{projectRoot}',\n env: { PORT: `${port}` },\n },\n dependsOn: [] as Array<string | { projects: string[]; target: string }>,\n });\n let project: ProjectConfiguration;\n if (projectExists(tree, fullyQualifiedName)) {\n project = readProjectConfigurationUnqualified(tree, fullyQualifiedName);\n } else {\n addProjectConfiguration(tree, fullyQualifiedName, {\n name: fullyQualifiedName,\n root: projectRoot,\n projectType: 'library',\n sourceRoot: projectRoot,\n tags: [],\n targets: {},\n metadata: {\n generator: AGENTCORE_GATEWAY_GENERATOR_INFO.id,\n } as any,\n });\n project = readProjectConfigurationUnqualified(tree, fullyQualifiedName);\n }\n // Ensure the project has its own package.json so its runtime dependencies\n // (added below) are declared in it rather than the workspace root.\n ensureProjectPackageJson(tree, {\n dir: projectRoot,\n fullyQualifiedName,\n });\n const port = assignPort(tree, project, 8100);\n // A gateway is its own standalone project, so it uses plain `serve` / `dev`\n // targets. Re-run: keep existing targets (their dependsOn may have been\n // populated by the mcp-connection generator), just ensure both exist.\n project.targets ??= {};\n project.targets['serve'] ??= localGatewayTarget(port);\n project.targets['dev'] ??= localGatewayTarget(port);\n updateProjectConfiguration(tree, project.name, project);\n\n // Scaffold the gateway project: local-dev.ts (+ Cedar policies if requested)\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'project'),\n projectRoot,\n { nameClassName, nameKebabCase: name, port, attachedMcpServers: [] },\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n if (cedarPolicy) {\n // The default permit-all policy differs by auth type: AgentCore represents\n // IAM callers as `AgentCore::IamEntity` and Cognito/JWT callers as\n // `AgentCore::OAuthUser`, so the two policies match different principals.\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'cedar'),\n projectRoot,\n { nameClassName, auth },\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n }\n\n // Recorded in the metadata below so the version sync can tell a CDK\n // project from a Terraform one; undefined when no infrastructure was\n // generated, in which case neither provider's packages were added.\n const iac =\n infra !== 'none' ? await resolveIac(tree, options.iac) : undefined;\n\n // Recorded below and read by the declaration's predicates, so the packages\n // added here are exactly the ones the version sync will own.\n const metadata: AgentCoreGatewayMetadata = {\n name,\n rc: nameClassName,\n protocol,\n auth,\n port,\n ...(iac ? { iac } : {}),\n };\n\n addGeneratorMetadata(\n tree,\n fullyQualifiedName,\n AGENTCORE_GATEWAY_GENERATOR_INFO,\n metadata,\n );\n\n addTsDependencies(tree, DEPENDENCIES, { metadata, projectRoot });\n\n // Wire up infra (CDK or Terraform); re-running with infra=agentcore adds\n // the infrastructure to a previously infra-less gateway.\n\n if (infra === 'agentcore') {\n await sharedConstructsGenerator(tree, { iac }, DEPENDENCIES);\n\n await addAgentCoreGatewayInfra(\n tree,\n {\n gatewayNameClassName: nameClassName,\n gatewayNameKebabCase: name,\n projectName: fullyQualifiedName,\n projectDirectory: projectRoot,\n cedarPolicy,\n auth,\n iac,\n },\n DEPENDENCIES,\n );\n }\n\n await addGeneratorMetricsIfApplicable(tree, [\n AGENTCORE_GATEWAY_GENERATOR_INFO,\n ]);\n\n await formatFilesInSubtree(tree);\n return () =>\n installDependencies(tree, options.preferInstallDependencies, {\n languages: ['typescript'],\n });\n};\n\n/**\n * Gateway details stored in the gateway project's metadata.\n */\nexport interface AgentCoreGatewayMetadata extends IacMetadata {\n name: string;\n rc: string;\n protocol: string;\n auth: string;\n port: number;\n}\n\n/**\n * Read a gateway project's metadata, validating it was generated by the\n * agentcore-gateway generator.\n */\nexport const readAgentCoreGatewayMetadata = (\n project: ProjectConfiguration,\n): AgentCoreGatewayMetadata => {\n const metadata = project.metadata as any;\n if (metadata?.generator !== AGENTCORE_GATEWAY_GENERATOR_INFO.id) {\n throw new Error(\n `Project '${project.name}' was not generated by the '${AGENTCORE_GATEWAY_GENERATOR_INFO.id}' generator.`,\n );\n }\n return metadata as AgentCoreGatewayMetadata;\n};\n\nexport default agentcoreGatewayGenerator;\n"],"names":["addProjectConfiguration","generateFiles","joinPathFragments","OverwriteStrategy","updateProjectConfiguration","addTsDependencies","AGENT_CORE_CONSTRUCTS_DEPENDENCIES","addAgentCoreGatewayInfra","declareDependencies","ownedElsewhere","formatFilesInSubtree","resolveIac","installDependencies","addGeneratorMetricsIfApplicable","kebabCase","toClassName","getNpmScopePrefix","addGeneratorMetadata","getGeneratorInfo","projectExists","readProjectConfigurationUnqualified","assignPort","ensureProjectPackageJson","SHARED_CONSTRUCTS_DEPENDENCIES","sharedConstructsGenerator","DEPENDENCIES","ts","name","dev","root","AGENTCORE_GATEWAY_GENERATOR_INFO","filename","agentcoreGatewayGenerator","tree","options","nameClassName","parentDir","directory","subDir","subDirectory","projectRoot","fullyQualifiedName","protocol","auth","cedarPolicy","infra","localGatewayTarget","port","executor","continuous","command","cwd","env","PORT","dependsOn","project","projectType","sourceRoot","tags","targets","metadata","generator","id","dir","dirname","nameKebabCase","attachedMcpServers","overwriteStrategy","KeepExisting","iac","undefined","rc","gatewayNameClassName","gatewayNameKebabCase","projectName","projectDirectory","preferInstallDependencies","languages","readAgentCoreGatewayMetadata","Error"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../packages/nx-plugin/src/agentcore-gateway/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n addProjectConfiguration,\n type GeneratorCallback,\n generateFiles,\n joinPathFragments,\n logger,\n OverwriteStrategy,\n type ProjectConfiguration,\n type Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport { addTsDependencies } from '../utils/add-dependencies';\nimport {\n AGENT_CORE_CONSTRUCTS_DEPENDENCIES,\n AGENT_CORE_CONSTRUCTS_PY_DEPENDENCIES,\n addAgentCoreGatewayInfra,\n} from '../utils/agent-core-constructs/agent-core-constructs';\nimport {\n declareDependencies,\n ownedElsewhere,\n} from '../utils/declared-dependencies';\nimport { formatFilesInSubtree } from '../utils/format';\nimport { resolveIac } from '../utils/iac';\nimport { installDependencies } from '../utils/install';\nimport { addGeneratorMetricsIfApplicable } from '../utils/metrics';\nimport { kebabCase, toClassName } from '../utils/names';\nimport { getNpmScopePrefix } from '../utils/npm-scope';\nimport {\n addGeneratorMetadata,\n getGeneratorInfo,\n type NxGeneratorInfo,\n projectExists,\n readProjectConfigurationUnqualified,\n} from '../utils/nx';\nimport { assignPort } from '../utils/port';\nimport { ensureProjectPackageJson } from '../utils/project-package-json';\nimport {\n SHARED_CONSTRUCTS_DEPENDENCIES,\n sharedConstructsGenerator,\n} from '../utils/shared-constructs';\nimport type { IacMetadata } from '../utils/shared-constructs-constants';\nimport type { AgentcoreGatewayGeneratorSchema } from './schema';\n\n// The gateway's local-dev server and Cedar policy rendering need these\n// whatever the auth; only the MCP SDK is protocol-specific (the http local\n// gateway is a plain proxy).\nexport const DEPENDENCIES = declareDependencies<AgentCoreGatewayMetadata>()({\n ts: [\n { name: '@modelcontextprotocol/sdk', when: (m) => m.protocol === 'mcp' },\n { name: 'express' },\n { name: '@types/express', dev: true },\n // ejs renders the Cedar policy in the shared gateway construct.\n { name: 'ejs', dev: true },\n { name: '@types/ejs', dev: true },\n // local-dev.ts runs via tsx, which is shared tooling.\n { name: 'tsx', dev: true, root: true },\n ...ownedElsewhere(AGENT_CORE_CONSTRUCTS_DEPENDENCIES),\n ...ownedElsewhere(SHARED_CONSTRUCTS_DEPENDENCIES),\n ],\n py: ownedElsewhere(AGENT_CORE_CONSTRUCTS_PY_DEPENDENCIES),\n});\n\nexport const AGENTCORE_GATEWAY_GENERATOR_INFO: NxGeneratorInfo =\n getGeneratorInfo(import.meta.filename);\n\nexport const agentcoreGatewayGenerator = async (\n tree: Tree,\n options: AgentcoreGatewayGeneratorSchema,\n): Promise<GeneratorCallback> => {\n const name = kebabCase(options.name);\n const nameClassName = toClassName(name);\n const parentDir = options.directory ?? 'packages';\n const subDir = options.subDirectory ?? name;\n const projectRoot = joinPathFragments(parentDir, subDir);\n const fullyQualifiedName = `${getNpmScopePrefix(tree)}${name}`;\n\n // Protocol is mcp (aggregate MCP server targets into one MCP endpoint) or\n // http (proxy agent runtime targets via path-based routing). Persisted in\n // metadata so connection generators can validate it.\n const protocol = options.protocol ?? 'mcp';\n // Inbound auth is iam (default) or cognito. Persisted in metadata so\n // connection generators can validate it (agent -> gateway connections\n // require an IAM gateway).\n const auth = options.auth ?? 'iam';\n // Cedar policies authorize MCP tool actions, which an http gateway has none\n // of — its runtime targets are plain proxied endpoints — so the policy\n // engine only applies to mcp gateways. cedarPolicy defaults to true in the\n // schema, so an http gateway quietly drops it rather than requiring\n // --cedarPolicy=false.\n if (protocol === 'http' && options.cedarPolicy) {\n logger.warn(\n 'Cedar policies authorize MCP tool actions, so cedarPolicy is ignored for http-protocol gateways.',\n );\n }\n const cedarPolicy = protocol === 'mcp' && (options.cedarPolicy ?? true);\n const infra = options.infra ?? 'agentcore';\n\n // local-dev.ts is the local gateway: a continuous MCP aggregator chaining\n // onto attached MCP servers' dev targets (added by the mcp-connection\n // generator), so a single `nx dev <gateway>` boots the gateway and every\n // attached MCP server together.\n //\n // `serve` exists for parity with other generators; the deployed Gateway is\n // a managed AWS resource, so `serve`-mode agents talk to it via runtime\n // config and the local gateway sits idle.\n const localGatewayTarget = (port: number) => ({\n executor: 'nx:run-commands' as const,\n continuous: true,\n options: {\n command: 'tsx local-dev.ts',\n cwd: '{projectRoot}',\n env: { PORT: `${port}` },\n },\n dependsOn: [] as Array<string | { projects: string[]; target: string }>,\n });\n let project: ProjectConfiguration;\n if (projectExists(tree, fullyQualifiedName)) {\n project = readProjectConfigurationUnqualified(tree, fullyQualifiedName);\n } else {\n addProjectConfiguration(tree, fullyQualifiedName, {\n name: fullyQualifiedName,\n root: projectRoot,\n projectType: 'library',\n sourceRoot: projectRoot,\n tags: [],\n targets: {},\n metadata: {\n generator: AGENTCORE_GATEWAY_GENERATOR_INFO.id,\n } as any,\n });\n project = readProjectConfigurationUnqualified(tree, fullyQualifiedName);\n }\n // Ensure the project has its own package.json so its runtime dependencies\n // (added below) are declared in it rather than the workspace root.\n ensureProjectPackageJson(tree, {\n dir: projectRoot,\n fullyQualifiedName,\n });\n const port = assignPort(tree, project, 8100);\n // A gateway is its own standalone project, so it uses plain `serve` / `dev`\n // targets. Re-run: keep existing targets (their dependsOn may have been\n // populated by the mcp-connection generator), just ensure both exist.\n project.targets ??= {};\n project.targets['serve'] ??= localGatewayTarget(port);\n project.targets['dev'] ??= localGatewayTarget(port);\n updateProjectConfiguration(tree, project.name, project);\n\n // Scaffold the gateway project: local-dev.ts (+ Cedar policies if requested)\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'project', protocol),\n projectRoot,\n {\n nameClassName,\n nameKebabCase: name,\n port,\n attachedMcpServers: [],\n attachedAgents: [],\n },\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n if (cedarPolicy) {\n // The default permit-all policy differs by auth type: AgentCore represents\n // IAM callers as `AgentCore::IamEntity` and Cognito/JWT callers as\n // `AgentCore::OAuthUser`, so the two policies match different principals.\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'cedar'),\n projectRoot,\n { nameClassName, auth },\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n }\n\n // Recorded in the metadata below so the version sync can tell a CDK\n // project from a Terraform one; undefined when no infrastructure was\n // generated, in which case neither provider's packages were added.\n const iac =\n infra !== 'none' ? await resolveIac(tree, options.iac) : undefined;\n\n // Recorded below and read by the declaration's predicates, so the packages\n // added here are exactly the ones the version sync will own.\n const metadata: AgentCoreGatewayMetadata = {\n name,\n rc: nameClassName,\n protocol,\n auth,\n port,\n ...(iac ? { iac } : {}),\n };\n\n addGeneratorMetadata(\n tree,\n fullyQualifiedName,\n AGENTCORE_GATEWAY_GENERATOR_INFO,\n metadata,\n );\n\n addTsDependencies(tree, DEPENDENCIES, { metadata, projectRoot });\n\n // Wire up infra (CDK or Terraform); re-running with infra=agentcore adds\n // the infrastructure to a previously infra-less gateway.\n\n if (infra === 'agentcore') {\n await sharedConstructsGenerator(tree, { iac }, DEPENDENCIES);\n\n await addAgentCoreGatewayInfra(\n tree,\n {\n gatewayNameClassName: nameClassName,\n gatewayNameKebabCase: name,\n projectName: fullyQualifiedName,\n projectDirectory: projectRoot,\n cedarPolicy,\n auth,\n protocol,\n iac,\n },\n DEPENDENCIES,\n );\n }\n\n await addGeneratorMetricsIfApplicable(tree, [\n AGENTCORE_GATEWAY_GENERATOR_INFO,\n ]);\n\n await formatFilesInSubtree(tree);\n return () =>\n installDependencies(tree, options.preferInstallDependencies, {\n languages: ['typescript'],\n });\n};\n\n/**\n * Gateway details stored in the gateway project's metadata.\n */\nexport interface AgentCoreGatewayMetadata extends IacMetadata {\n name: string;\n rc: string;\n protocol: string;\n auth: string;\n port: number;\n}\n\n/**\n * Read a gateway project's metadata, validating it was generated by the\n * agentcore-gateway generator.\n */\nexport const readAgentCoreGatewayMetadata = (\n project: ProjectConfiguration,\n): AgentCoreGatewayMetadata => {\n const metadata = project.metadata as any;\n if (metadata?.generator !== AGENTCORE_GATEWAY_GENERATOR_INFO.id) {\n throw new Error(\n `Project '${project.name}' was not generated by the '${AGENTCORE_GATEWAY_GENERATOR_INFO.id}' generator.`,\n );\n }\n return metadata as AgentCoreGatewayMetadata;\n};\n\nexport default agentcoreGatewayGenerator;\n"],"names":["addProjectConfiguration","generateFiles","joinPathFragments","logger","OverwriteStrategy","updateProjectConfiguration","addTsDependencies","AGENT_CORE_CONSTRUCTS_DEPENDENCIES","AGENT_CORE_CONSTRUCTS_PY_DEPENDENCIES","addAgentCoreGatewayInfra","declareDependencies","ownedElsewhere","formatFilesInSubtree","resolveIac","installDependencies","addGeneratorMetricsIfApplicable","kebabCase","toClassName","getNpmScopePrefix","addGeneratorMetadata","getGeneratorInfo","projectExists","readProjectConfigurationUnqualified","assignPort","ensureProjectPackageJson","SHARED_CONSTRUCTS_DEPENDENCIES","sharedConstructsGenerator","DEPENDENCIES","ts","name","when","m","protocol","dev","root","py","AGENTCORE_GATEWAY_GENERATOR_INFO","filename","agentcoreGatewayGenerator","tree","options","nameClassName","parentDir","directory","subDir","subDirectory","projectRoot","fullyQualifiedName","auth","cedarPolicy","warn","infra","localGatewayTarget","port","executor","continuous","command","cwd","env","PORT","dependsOn","project","projectType","sourceRoot","tags","targets","metadata","generator","id","dir","dirname","nameKebabCase","attachedMcpServers","attachedAgents","overwriteStrategy","KeepExisting","iac","undefined","rc","gatewayNameClassName","gatewayNameKebabCase","projectName","projectDirectory","preferInstallDependencies","languages","readAgentCoreGatewayMetadata","Error"],"mappings":"AAAA;;;CAGC,GACD,SACEA,uBAAuB,EAEvBC,aAAa,EACbC,iBAAiB,EACjBC,MAAM,EACNC,iBAAiB,EAGjBC,0BAA0B,QACrB,aAAa;AACpB,SAASC,iBAAiB,QAAQ,+BAA4B;AAC9D,SACEC,kCAAkC,EAClCC,qCAAqC,EACrCC,wBAAwB,QACnB,0DAAuD;AAC9D,SACEC,mBAAmB,EACnBC,cAAc,QACT,oCAAiC;AACxC,SAASC,oBAAoB,QAAQ,qBAAkB;AACvD,SAASC,UAAU,QAAQ,kBAAe;AAC1C,SAASC,mBAAmB,QAAQ,sBAAmB;AACvD,SAASC,+BAA+B,QAAQ,sBAAmB;AACnE,SAASC,SAAS,EAAEC,WAAW,QAAQ,oBAAiB;AACxD,SAASC,iBAAiB,QAAQ,wBAAqB;AACvD,SACEC,oBAAoB,EACpBC,gBAAgB,EAEhBC,aAAa,EACbC,mCAAmC,QAC9B,iBAAc;AACrB,SAASC,UAAU,QAAQ,mBAAgB;AAC3C,SAASC,wBAAwB,QAAQ,mCAAgC;AACzE,SACEC,8BAA8B,EAC9BC,yBAAyB,QACpB,gCAA6B;AAIpC,uEAAuE;AACvE,2EAA2E;AAC3E,6BAA6B;AAC7B,OAAO,MAAMC,eAAejB,sBAAgD;IAC1EkB,IAAI;QACF;YAAEC,MAAM;YAA6BC,MAAM,CAACC,IAAMA,EAAEC,QAAQ,KAAK;QAAM;QACvE;YAAEH,MAAM;QAAU;QAClB;YAAEA,MAAM;YAAkBI,KAAK;QAAK;QACpC,gEAAgE;QAChE;YAAEJ,MAAM;YAAOI,KAAK;QAAK;QACzB;YAAEJ,MAAM;YAAcI,KAAK;QAAK;QAChC,sDAAsD;QACtD;YAAEJ,MAAM;YAAOI,KAAK;YAAMC,MAAM;QAAK;WAClCvB,eAAeJ;WACfI,eAAec;KACnB;IACDU,IAAIxB,eAAeH;AACrB,GAAG;AAEH,OAAO,MAAM4B,mCACXhB,iBAAiB,YAAYiB,QAAQ,EAAE;AAEzC,OAAO,MAAMC,4BAA4B,OACvCC,MACAC;IAEA,MAAMX,OAAOb,UAAUwB,QAAQX,IAAI;IACnC,MAAMY,gBAAgBxB,YAAYY;IAClC,MAAMa,YAAYF,QAAQG,SAAS,IAAI;IACvC,MAAMC,SAASJ,QAAQK,YAAY,IAAIhB;IACvC,MAAMiB,cAAc5C,kBAAkBwC,WAAWE;IACjD,MAAMG,qBAAqB,GAAG7B,kBAAkBqB,QAAQV,MAAM;IAE9D,0EAA0E;IAC1E,0EAA0E;IAC1E,qDAAqD;IACrD,MAAMG,WAAWQ,QAAQR,QAAQ,IAAI;IACrC,qEAAqE;IACrE,sEAAsE;IACtE,2BAA2B;IAC3B,MAAMgB,OAAOR,QAAQQ,IAAI,IAAI;IAC7B,4EAA4E;IAC5E,uEAAuE;IACvE,2EAA2E;IAC3E,oEAAoE;IACpE,uBAAuB;IACvB,IAAIhB,aAAa,UAAUQ,QAAQS,WAAW,EAAE;QAC9C9C,OAAO+C,IAAI,CACT;IAEJ;IACA,MAAMD,cAAcjB,aAAa,SAAUQ,CAAAA,QAAQS,WAAW,IAAI,IAAG;IACrE,MAAME,QAAQX,QAAQW,KAAK,IAAI;IAE/B,0EAA0E;IAC1E,sEAAsE;IACtE,yEAAyE;IACzE,gCAAgC;IAChC,EAAE;IACF,2EAA2E;IAC3E,wEAAwE;IACxE,0CAA0C;IAC1C,MAAMC,qBAAqB,CAACC,OAAkB,CAAA;YAC5CC,UAAU;YACVC,YAAY;YACZf,SAAS;gBACPgB,SAAS;gBACTC,KAAK;gBACLC,KAAK;oBAAEC,MAAM,GAAGN,MAAM;gBAAC;YACzB;YACAO,WAAW,EAAE;QACf,CAAA;IACA,IAAIC;IACJ,IAAIxC,cAAckB,MAAMQ,qBAAqB;QAC3Cc,UAAUvC,oCAAoCiB,MAAMQ;IACtD,OAAO;QACL/C,wBAAwBuC,MAAMQ,oBAAoB;YAChDlB,MAAMkB;YACNb,MAAMY;YACNgB,aAAa;YACbC,YAAYjB;YACZkB,MAAM,EAAE;YACRC,SAAS,CAAC;YACVC,UAAU;gBACRC,WAAW/B,iCAAiCgC,EAAE;YAChD;QACF;QACAP,UAAUvC,oCAAoCiB,MAAMQ;IACtD;IACA,0EAA0E;IAC1E,mEAAmE;IACnEvB,yBAAyBe,MAAM;QAC7B8B,KAAKvB;QACLC;IACF;IACA,MAAMM,OAAO9B,WAAWgB,MAAMsB,SAAS;IACvC,4EAA4E;IAC5E,wEAAwE;IACxE,sEAAsE;IACtEA,QAAQI,OAAO,KAAK,CAAC;IACrBJ,QAAQI,OAAO,CAAC,QAAQ,KAAKb,mBAAmBC;IAChDQ,QAAQI,OAAO,CAAC,MAAM,KAAKb,mBAAmBC;IAC9ChD,2BAA2BkC,MAAMsB,QAAQhC,IAAI,EAAEgC;IAE/C,6EAA6E;IAC7E5D,cACEsC,MACArC,kBAAkB,YAAYoE,OAAO,EAAE,SAAS,WAAWtC,WAC3Dc,aACA;QACEL;QACA8B,eAAe1C;QACfwB;QACAmB,oBAAoB,EAAE;QACtBC,gBAAgB,EAAE;IACpB,GACA;QAAEC,mBAAmBtE,kBAAkBuE,YAAY;IAAC;IAEtD,IAAI1B,aAAa;QACf,2EAA2E;QAC3E,mEAAmE;QACnE,0EAA0E;QAC1EhD,cACEsC,MACArC,kBAAkB,YAAYoE,OAAO,EAAE,SAAS,UAChDxB,aACA;YAAEL;YAAeO;QAAK,GACtB;YAAE0B,mBAAmBtE,kBAAkBuE,YAAY;QAAC;IAExD;IAEA,oEAAoE;IACpE,qEAAqE;IACrE,mEAAmE;IACnE,MAAMC,MACJzB,UAAU,SAAS,MAAMtC,WAAW0B,MAAMC,QAAQoC,GAAG,IAAIC;IAE3D,2EAA2E;IAC3E,6DAA6D;IAC7D,MAAMX,WAAqC;QACzCrC;QACAiD,IAAIrC;QACJT;QACAgB;QACAK;QACA,GAAIuB,MAAM;YAAEA;QAAI,IAAI,CAAC,CAAC;IACxB;IAEAzD,qBACEoB,MACAQ,oBACAX,kCACA8B;IAGF5D,kBAAkBiC,MAAMZ,cAAc;QAAEuC;QAAUpB;IAAY;IAE9D,yEAAyE;IACzE,yDAAyD;IAEzD,IAAIK,UAAU,aAAa;QACzB,MAAMzB,0BAA0Ba,MAAM;YAAEqC;QAAI,GAAGjD;QAE/C,MAAMlB,yBACJ8B,MACA;YACEwC,sBAAsBtC;YACtBuC,sBAAsBnD;YACtBoD,aAAalC;YACbmC,kBAAkBpC;YAClBG;YACAD;YACAhB;YACA4C;QACF,GACAjD;IAEJ;IAEA,MAAMZ,gCAAgCwB,MAAM;QAC1CH;KACD;IAED,MAAMxB,qBAAqB2B;IAC3B,OAAO,IACLzB,oBAAoByB,MAAMC,QAAQ2C,yBAAyB,EAAE;YAC3DC,WAAW;gBAAC;aAAa;QAC3B;AACJ,EAAE;AAaF;;;CAGC,GACD,OAAO,MAAMC,+BAA+B,CAC1CxB;IAEA,MAAMK,WAAWL,QAAQK,QAAQ;IACjC,IAAIA,UAAUC,cAAc/B,iCAAiCgC,EAAE,EAAE;QAC/D,MAAM,IAAIkB,MACR,CAAC,SAAS,EAAEzB,QAAQhC,IAAI,CAAC,4BAA4B,EAAEO,iCAAiCgC,EAAE,CAAC,YAAY,CAAC;IAE5G;IACA,OAAOF;AACT,EAAE;AAEF,eAAe5B,0BAA0B"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`agentcore-gateway#react-connection generator > generates a gateway-routed AG-UI hook for each fronted agent > useAguiMyAgent.tsx 1`] = `
|
|
4
|
+
"import { HttpAgent } from '@ag-ui/client';
|
|
5
|
+
import type { AbstractAgent, RunAgentInput } from '@ag-ui/client';
|
|
6
|
+
import { useMemo } from 'react';
|
|
7
|
+
import { useRuntimeConfig } from './useRuntimeConfig';
|
|
8
|
+
import { useSigV4, type SigV4Client } from './useSigV4';
|
|
9
|
+
|
|
10
|
+
// The agent sits behind an AgentCore Gateway, which proxies
|
|
11
|
+
// \`/<targetName>/invocations\` to the agent runtime.
|
|
12
|
+
function buildGatewayUrl(gatewayUrl: string): string {
|
|
13
|
+
return \`\${new URL(gatewayUrl).origin}/my-agent/invocations\`;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// AgentCore session ids must be at least 33 characters.
|
|
17
|
+
function agentCoreSessionId(input: RunAgentInput): string {
|
|
18
|
+
return (input.threadId ?? '').padEnd(33, '0');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
class SigV4HttpAgent extends HttpAgent {
|
|
22
|
+
sigV4Client: SigV4Client;
|
|
23
|
+
|
|
24
|
+
constructor(
|
|
25
|
+
config: ConstructorParameters<typeof HttpAgent>[0],
|
|
26
|
+
sigV4Client: SigV4Client,
|
|
27
|
+
) {
|
|
28
|
+
super({
|
|
29
|
+
...config,
|
|
30
|
+
fetch: sigV4Client.fetch as (
|
|
31
|
+
url: string,
|
|
32
|
+
init: RequestInit,
|
|
33
|
+
) => Promise<Response>,
|
|
34
|
+
});
|
|
35
|
+
this.sigV4Client = sigV4Client;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
protected override requestInit(input: RunAgentInput): RequestInit {
|
|
39
|
+
const init = super.requestInit(input);
|
|
40
|
+
init.headers = {
|
|
41
|
+
...(init.headers as Record<string, string>),
|
|
42
|
+
'X-Amzn-Bedrock-AgentCore-Runtime-Session-Id': agentCoreSessionId(input),
|
|
43
|
+
};
|
|
44
|
+
return init;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
override clone(): SigV4HttpAgent {
|
|
48
|
+
const cloned = super.clone() as SigV4HttpAgent;
|
|
49
|
+
cloned.sigV4Client = this.sigV4Client;
|
|
50
|
+
return cloned;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export const useAguiMyAgent = (): Record<string, AbstractAgent> => {
|
|
55
|
+
const runtimeConfig = useRuntimeConfig();
|
|
56
|
+
const gatewayUrl = runtimeConfig.gateways.MyGateway;
|
|
57
|
+
const sigv4 = useSigV4();
|
|
58
|
+
|
|
59
|
+
const url = useMemo(() => buildGatewayUrl(gatewayUrl), [gatewayUrl]);
|
|
60
|
+
|
|
61
|
+
return useMemo((): Record<string, AbstractAgent> => {
|
|
62
|
+
const agent = new SigV4HttpAgent({ url }, sigv4);
|
|
63
|
+
|
|
64
|
+
return { 'my-agent': agent };
|
|
65
|
+
}, [url, sigv4]);
|
|
66
|
+
};
|
|
67
|
+
"
|
|
68
|
+
`;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import { type Tree } from '@nx/devkit';
|
|
6
|
+
import { type NxGeneratorInfo } from '../../utils/nx';
|
|
7
|
+
import type { AgentcoreGatewayReactConnectionGeneratorSchema } from './schema';
|
|
8
|
+
export declare const AGENTCORE_GATEWAY_REACT_CONNECTION_GENERATOR_INFO: NxGeneratorInfo;
|
|
9
|
+
/**
|
|
10
|
+
* Connect a React website to an AgentCore Gateway fronting agents.
|
|
11
|
+
*
|
|
12
|
+
* For each agent attached to the gateway (via the
|
|
13
|
+
* `agentcore-gateway#agent-connection` generator), generates the same website
|
|
14
|
+
* client as connecting to the agent directly, but routed through the
|
|
15
|
+
* gateway's `/<targetName>` path — so the browser only needs to reach the
|
|
16
|
+
* gateway, and the agent runtimes can sit in a VPC behind it.
|
|
17
|
+
*/
|
|
18
|
+
export declare const agentcoreGatewayReactConnectionGenerator: (tree: Tree, options: AgentcoreGatewayReactConnectionGeneratorSchema) => Promise<() => Promise<void>>;
|
|
19
|
+
export default agentcoreGatewayReactConnectionGenerator;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/ import { getProjects, logger } from "@nx/devkit";
|
|
5
|
+
import { addGatewayTargetToLocalDev } from "../../connection/agent-local-dev.js";
|
|
6
|
+
import { addGatewayUrlToConnectionNamespace } from "../../connection/gateway-runtime-config.js";
|
|
7
|
+
import { PY_AGENT_GENERATOR_INFO } from "../../py/agent/generator.js";
|
|
8
|
+
import { pyAgentReactConnectionGenerator } from "../../py/agent/react-connection/generator.js";
|
|
9
|
+
import { TS_AGENT_GENERATOR_INFO } from "../../ts/agent/generator.js";
|
|
10
|
+
import { tsAgentReactConnectionGenerator } from "../../ts/agent/react-connection/generator.js";
|
|
11
|
+
import { formatFilesInSubtree } from "../../utils/format.js";
|
|
12
|
+
import { installDependencies } from "../../utils/install.js";
|
|
13
|
+
import { addGeneratorMetricsIfApplicable } from "../../utils/metrics.js";
|
|
14
|
+
import { kebabCase } from "../../utils/names.js";
|
|
15
|
+
import { addComponentGeneratorMetadata, getGeneratorInfo, readProjectConfigurationUnqualified } from "../../utils/nx.js";
|
|
16
|
+
import { AGENTCORE_GATEWAY_AGENT_CONNECTION_GENERATOR_INFO } from "../agent-connection/generator.js";
|
|
17
|
+
import { readAgentCoreGatewayMetadata } from "../generator.js";
|
|
18
|
+
export const AGENTCORE_GATEWAY_REACT_CONNECTION_GENERATOR_INFO = getGeneratorInfo(import.meta.filename);
|
|
19
|
+
/**
|
|
20
|
+
* Connect a React website to an AgentCore Gateway fronting agents.
|
|
21
|
+
*
|
|
22
|
+
* For each agent attached to the gateway (via the
|
|
23
|
+
* `agentcore-gateway#agent-connection` generator), generates the same website
|
|
24
|
+
* client as connecting to the agent directly, but routed through the
|
|
25
|
+
* gateway's `/<targetName>` path — so the browser only needs to reach the
|
|
26
|
+
* gateway, and the agent runtimes can sit in a VPC behind it.
|
|
27
|
+
*/ export const agentcoreGatewayReactConnectionGenerator = async (tree, options)=>{
|
|
28
|
+
const frontendProject = readProjectConfigurationUnqualified(tree, options.sourceProject);
|
|
29
|
+
const gatewayProject = readProjectConfigurationUnqualified(tree, options.targetProject);
|
|
30
|
+
const gateway = readAgentCoreGatewayMetadata(gatewayProject);
|
|
31
|
+
if (gateway.protocol !== 'http') {
|
|
32
|
+
throw new Error(`Gateway '${gateway.name}' has protocol='${gateway.protocol}'. Websites can only connect to http-protocol gateways, which proxy requests to their agent targets.`);
|
|
33
|
+
}
|
|
34
|
+
// A2A targets speak agent-to-agent JSON-RPC, not a browser protocol, so
|
|
35
|
+
// the website only connects to the gateway's AG-UI / HTTP agents. A gateway
|
|
36
|
+
// with none attached yet still gets its URL published and dev wiring —
|
|
37
|
+
// re-running this connection after attaching agents generates their
|
|
38
|
+
// website clients.
|
|
39
|
+
const agents = frontedAgents(tree, gatewayProject.name).filter((agent)=>(agent.component.protocol ?? '').toLowerCase() !== 'a2a');
|
|
40
|
+
if (agents.length === 0) {
|
|
41
|
+
logger.warn(`Gateway '${gateway.name}' has no AG-UI or HTTP agents attached, so no website clients were generated. Connect agents to the gateway, then re-run this connection to generate their clients.`);
|
|
42
|
+
}
|
|
43
|
+
// One website client per fronted agent, routed through the gateway.
|
|
44
|
+
for (const agent of agents){
|
|
45
|
+
const generator = agent.language === 'ts' ? tsAgentReactConnectionGenerator : pyAgentReactConnectionGenerator;
|
|
46
|
+
await generator(tree, {
|
|
47
|
+
sourceProject: frontendProject.name,
|
|
48
|
+
targetProject: agent.projectName,
|
|
49
|
+
targetComponent: agent.component,
|
|
50
|
+
preferInstallDependencies: options.preferInstallDependencies,
|
|
51
|
+
gatewayRoute: {
|
|
52
|
+
gatewayClassName: gateway.rc,
|
|
53
|
+
targetName: agent.targetName,
|
|
54
|
+
gatewayAuth: gateway.auth
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
// Publish the gateway URL to the website via the 'connection' namespace.
|
|
59
|
+
await addGatewayUrlToConnectionNamespace(tree, {
|
|
60
|
+
gatewayNameKebabCase: kebabCase(gateway.rc),
|
|
61
|
+
gatewayNameClassName: gateway.rc
|
|
62
|
+
});
|
|
63
|
+
// Wire the website's dev target to the local gateway, which proxies to the
|
|
64
|
+
// attached agents (transitively starting them via its own dev dependencies).
|
|
65
|
+
await addGatewayTargetToLocalDev(tree, frontendProject.name, gatewayProject.name, {
|
|
66
|
+
gatewayClassName: gateway.rc,
|
|
67
|
+
port: gateway.port
|
|
68
|
+
});
|
|
69
|
+
// Recorded so the version sync can identify this connection.
|
|
70
|
+
addComponentGeneratorMetadata(tree, frontendProject.name, AGENTCORE_GATEWAY_REACT_CONNECTION_GENERATOR_INFO, gatewayProject.root, gateway.rc);
|
|
71
|
+
await addGeneratorMetricsIfApplicable(tree, [
|
|
72
|
+
AGENTCORE_GATEWAY_REACT_CONNECTION_GENERATOR_INFO
|
|
73
|
+
]);
|
|
74
|
+
await formatFilesInSubtree(tree);
|
|
75
|
+
return ()=>installDependencies(tree, options.preferInstallDependencies, {
|
|
76
|
+
languages: [
|
|
77
|
+
'typescript'
|
|
78
|
+
]
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* The agents attached to the gateway, resolved from the connection entries
|
|
83
|
+
* the `agentcore-gateway#agent-connection` generator recorded: each names the
|
|
84
|
+
* agent project by root (`path`) and its gateway target name (`name`), which
|
|
85
|
+
* matches the agent component's class name in kebab-case.
|
|
86
|
+
*/ const frontedAgents = (tree, gatewayProjectName)=>{
|
|
87
|
+
const gatewayProject = readProjectConfigurationUnqualified(tree, gatewayProjectName);
|
|
88
|
+
const connections = (gatewayProject.metadata?.components ?? []).filter((c)=>c.generator === AGENTCORE_GATEWAY_AGENT_CONNECTION_GENERATOR_INFO.id);
|
|
89
|
+
const projectsByRoot = new Map([
|
|
90
|
+
...getProjects(tree).values()
|
|
91
|
+
].map((p)=>[
|
|
92
|
+
p.root,
|
|
93
|
+
p
|
|
94
|
+
]));
|
|
95
|
+
return connections.flatMap((connection)=>{
|
|
96
|
+
const agentProject = connection.path ? projectsByRoot.get(connection.path) : undefined;
|
|
97
|
+
if (!agentProject) {
|
|
98
|
+
return [];
|
|
99
|
+
}
|
|
100
|
+
const component = (agentProject.metadata?.components ?? []).find((c)=>[
|
|
101
|
+
TS_AGENT_GENERATOR_INFO.id,
|
|
102
|
+
PY_AGENT_GENERATOR_INFO.id
|
|
103
|
+
].includes(c.generator) && kebabCase(c.rc ?? '') === connection.name);
|
|
104
|
+
if (!component) {
|
|
105
|
+
return [];
|
|
106
|
+
}
|
|
107
|
+
return [
|
|
108
|
+
{
|
|
109
|
+
projectName: agentProject.name,
|
|
110
|
+
component,
|
|
111
|
+
targetName: connection.name,
|
|
112
|
+
language: component.generator === TS_AGENT_GENERATOR_INFO.id ? 'ts' : 'py'
|
|
113
|
+
}
|
|
114
|
+
];
|
|
115
|
+
});
|
|
116
|
+
};
|
|
117
|
+
export default agentcoreGatewayReactConnectionGenerator;
|
|
118
|
+
|
|
119
|
+
//# sourceMappingURL=generator.js.map
|