@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.
- package/generators.json +17 -1
- package/migrations.json +12 -7
- package/package.json +1 -1
- 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 +1 -0
- package/src/agentcore-gateway/generator.js +22 -10
- 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 +2 -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 +107 -0
- package/src/connection/scaffold-catalog.js +140 -0
- package/src/connection/scaffold-catalog.js.map +1 -1
- 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/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.d.ts +6 -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/v1.0.0-rc.50/modernize-function-props-cast/metadata.json +3 -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/terraform-bootstrap-adopt-existing-bucket/metadata.json +3 -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.54/order-access-log-delivery-after-bucket-policy/metadata.json +3 -0
- package/src/migrations/v1.0.0-rc.55/backfill-generator-metadata/metadata.json +3 -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.57/ts-agent-session-management-support/metadata.json +3 -0
- package/src/py/agent/__snapshots__/generator.constructs.spec.ts.snap +2 -0
- 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/ts/agent/__snapshots__/generator.spec.ts.snap +4 -0
- 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/nx-migration/generator.js +40 -27
- package/src/ts/nx-migration/generator.js.map +1 -1
- 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/utils/agent-core-constructs/agent-core-constructs.d.ts +5 -0
- package/src/utils/agent-core-constructs/agent-core-constructs.js +2 -0
- 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/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/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/version-upgrade-migration/register.d.ts +4 -2
- package/src/utils/version-upgrade-migration/register.js +13 -13
- package/src/utils/version-upgrade-migration/register.js.map +1 -1
- /package/src/agentcore-gateway/files/project/{local-dev.ts.template → mcp/local-dev.ts.template} +0 -0
|
@@ -156,6 +156,7 @@ const addAgentCoreGatewayCDKInfra = async (tree, options, declaration)=>{
|
|
|
156
156
|
projectDirectory: options.projectDirectory,
|
|
157
157
|
cedarPolicy: options.cedarPolicy,
|
|
158
158
|
auth: options.auth,
|
|
159
|
+
protocol: options.protocol,
|
|
159
160
|
...esmVars(tree)
|
|
160
161
|
}, {
|
|
161
162
|
overwriteStrategy: OverwriteStrategy.KeepExisting
|
|
@@ -184,6 +185,7 @@ const addAgentCoreGatewayTerraformInfra = (tree, options)=>{
|
|
|
184
185
|
projectDirectory: options.projectDirectory,
|
|
185
186
|
cedarPolicy: options.cedarPolicy,
|
|
186
187
|
auth: options.auth,
|
|
188
|
+
protocol: options.protocol,
|
|
187
189
|
boto3Version: PY_VERSIONS.boto3,
|
|
188
190
|
httpxVersion: PY_VERSIONS.httpx,
|
|
189
191
|
mcpVersion: PY_VERSIONS.mcp,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/utils/agent-core-constructs/agent-core-constructs.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n generateFiles,\n joinPathFragments,\n OverwriteStrategy,\n type ProjectConfiguration,\n type Tree,\n updateJson,\n} from '@nx/devkit';\nimport { addStarExport } from '../ast';\nimport type { Containers } from '../containers';\nimport {\n type DeclaredPyDependency,\n type DeclaredTsDependency,\n type DependencyDeclaration,\n forDependencies,\n type MustDeclare,\n} from '../declared-dependencies';\nimport { addDependenciesToPackageJson } from '../dependencies';\nimport type { Iac } from '../iac';\nimport { esmVars } from '../module-format';\nimport { addDependencyToTargetIfNotPresent } from '../nx';\nimport {\n generatedInfrastructure,\n generatedTerraform,\n type IacMetadata,\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n SHARED_TERRAFORM_DIR,\n} from '../shared-constructs-constants';\nimport {\n type IPyDepVersion,\n type ITsDepVersion,\n PY_VERSIONS,\n terraformProviderVersions,\n withVersions,\n} from '../versions';\n\ntype IACProvider = { iac: Iac };\n\n/**\n * Dependencies a caller must declare to add an AgentCore Gateway construct.\n *\n * Gated on infrastructure having been generated, since the construct helpers only\n * run on that branch.\n */\nexport const AGENT_CORE_CONSTRUCTS_DEPENDENCIES = [\n { name: 'ejs', when: generatedInfrastructure },\n { name: '@aws-sdk/client-bedrock-agentcore', when: generatedInfrastructure },\n { name: '@types/ejs', when: generatedInfrastructure },\n] as const satisfies readonly DeclaredTsDependency<\n ITsDepVersion,\n IacMetadata\n>[];\n\n/**\n * Python versions the generated Terraform pins in an inline `uv run --with`\n * script, rather than in any `pyproject.toml`.\n *\n * Spread through `ownedElsewhere` because nothing installs them into the\n * workspace — the pin is owned so the version sync keeps it current, and gated on\n * Terraform since the CDK branch writes no such script.\n */\nexport const AGENT_CORE_CONSTRUCTS_PY_DEPENDENCIES = [\n { name: 'boto3', when: generatedTerraform },\n { name: 'httpx', when: generatedTerraform },\n { name: 'mcp', when: generatedTerraform },\n] as const satisfies readonly DeclaredPyDependency<\n IPyDepVersion,\n IacMetadata\n>[];\n\nexport type AgentCoreAuth = 'iam' | 'cognito';\n\nexport type AgentCoreSession = 's3' | 'in-memory';\n\nexport interface AddAgentCoreInfraProps {\n nameClassName: string;\n nameKebabCase: string;\n projectName: string;\n dockerImageTag: string;\n dockerOutputDir: string;\n appDirectory: string;\n serverProtocol: 'mcp' | 'http' | 'a2a';\n auth: AgentCoreAuth;\n /** How this runtime's session should be persisted. MCP servers have no session, so pass 'in-memory'. */\n session: AgentCoreSession;\n containers: Containers;\n}\n\nconst addAgentCoreInfra = async (\n tree: Tree,\n options: AddAgentCoreInfraProps & { iac: Iac },\n) => {\n switch (options.iac) {\n case 'cdk':\n await addAgentCoreCDKInfra(tree, options);\n break;\n case 'terraform':\n addAgentCoreTerraformInfra(tree, options);\n break;\n }\n\n // Update shared constructs/terraform project configuration to depend on this project\n updateJson(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n options.iac === 'cdk' ? SHARED_CONSTRUCTS_DIR : SHARED_TERRAFORM_DIR,\n 'project.json',\n ),\n (config: ProjectConfiguration) => {\n addDependencyToTargetIfNotPresent(\n config,\n 'build',\n `${options.projectName}:build`,\n );\n return config;\n },\n );\n};\n\nconst addAgentCoreCDKInfra = async (\n tree: Tree,\n options: AddAgentCoreInfraProps,\n) => {\n // Generate app specific CDK construct\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'cdk', 'app', 'agent-core'),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n options.appDirectory,\n ),\n { ...options, ...esmVars(tree) },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n // Export app specific CDK construct\n await addStarExport(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n options.appDirectory,\n 'index.ts',\n ),\n `./${options.nameKebabCase}/${options.nameKebabCase}.js`,\n );\n await addStarExport(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n 'index.ts',\n ),\n `./${options.appDirectory}/index.js`,\n );\n};\n\nconst addAgentCoreTerraformInfra = (\n tree: Tree,\n options: AddAgentCoreInfraProps,\n) => {\n // Add the AgentCore shared module\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'terraform',\n 'core',\n 'agent-core',\n ),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_TERRAFORM_DIR,\n 'src',\n 'core',\n 'agent-core',\n ),\n {\n containers: options.containers,\n boto3Version: PY_VERSIONS.boto3,\n ...terraformProviderVersions(),\n },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n // Generate app specific agent core configuration\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'terraform',\n 'app',\n 'agent-core',\n ),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_TERRAFORM_DIR,\n 'src',\n 'app',\n options.appDirectory,\n ),\n { ...options, ...terraformProviderVersions() },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n};\n\nexport interface AddMcpServerInfraProps {\n mcpServerNameClassName: string;\n mcpServerNameKebabCase: string;\n projectName: string;\n dockerImageTag: string;\n dockerOutputDir: string;\n auth: AgentCoreAuth;\n containers: Containers;\n}\n\n/**\n * Add an MCP server CDK construct\n */\nexport const addMcpServerInfra = async (\n tree: Tree,\n options: AddMcpServerInfraProps & IACProvider,\n) => {\n await addAgentCoreInfra(tree, {\n nameClassName: options.mcpServerNameClassName,\n nameKebabCase: options.mcpServerNameKebabCase,\n dockerImageTag: options.dockerImageTag,\n dockerOutputDir: options.dockerOutputDir,\n projectName: options.projectName,\n appDirectory: 'mcp-servers',\n serverProtocol: 'mcp',\n iac: options.iac,\n auth: options.auth,\n // MCP servers are stateless (no conversation session to persist).\n session: 'in-memory',\n containers: options.containers,\n });\n};\n\nexport interface AddAgentInfraProps {\n agentNameClassName: string;\n agentNameKebabCase: string;\n projectName: string;\n dockerImageTag: string;\n dockerOutputDir: string;\n auth: AgentCoreAuth;\n session: AgentCoreSession;\n serverProtocol?: 'http' | 'a2a';\n containers: Containers;\n}\n\n/**\n * Add an agent CDK construct\n */\nexport const addAgentInfra = async (\n tree: Tree,\n options: AddAgentInfraProps & IACProvider,\n) => {\n await addAgentCoreInfra(tree, {\n nameClassName: options.agentNameClassName,\n nameKebabCase: options.agentNameKebabCase,\n projectName: options.projectName,\n dockerImageTag: options.dockerImageTag,\n dockerOutputDir: options.dockerOutputDir,\n appDirectory: 'agents',\n session: options.session,\n serverProtocol: options.serverProtocol ?? 'http',\n iac: options.iac,\n auth: options.auth,\n containers: options.containers,\n });\n};\n\nexport interface AddAgentCoreGatewayInfraProps {\n gatewayNameClassName: string;\n gatewayNameKebabCase: string;\n projectName: string;\n projectDirectory: string;\n cedarPolicy: boolean;\n auth: AgentCoreAuth;\n}\n\nexport const addAgentCoreGatewayInfra = async <\n const D extends DependencyDeclaration,\n>(\n tree: Tree,\n options: AddAgentCoreGatewayInfraProps & IACProvider,\n declaration: D & MustDeclare<typeof AGENT_CORE_CONSTRUCTS_DEPENDENCIES, D>,\n) => {\n switch (options.iac) {\n case 'cdk':\n await addAgentCoreGatewayCDKInfra(tree, options, declaration);\n break;\n case 'terraform':\n addAgentCoreGatewayTerraformInfra(tree, options);\n break;\n }\n\n updateJson(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n options.iac === 'cdk' ? SHARED_CONSTRUCTS_DIR : SHARED_TERRAFORM_DIR,\n 'project.json',\n ),\n (config: ProjectConfiguration) => {\n addDependencyToTargetIfNotPresent(\n config,\n 'build',\n `${options.projectName}:build`,\n );\n return config;\n },\n );\n};\n\nconst addAgentCoreGatewayCDKInfra = async (\n tree: Tree,\n options: AddAgentCoreGatewayInfraProps,\n declaration: DependencyDeclaration,\n) => {\n // Generic gateway construct (readiness probe, policy engine, Cedar policy\n // loading) shared by all gateways\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'cdk',\n 'core',\n 'agentcore-gateway',\n ),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'core',\n 'agentcore-gateway',\n ),\n { ...esmVars(tree) },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'cdk',\n 'app',\n 'agentcore-gateway',\n ),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n 'gateways',\n ),\n {\n nameClassName: options.gatewayNameClassName,\n nameKebabCase: options.gatewayNameKebabCase,\n projectDirectory: options.projectDirectory,\n cedarPolicy: options.cedarPolicy,\n auth: options.auth,\n ...esmVars(tree),\n },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n await addStarExport(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'core',\n 'index.ts',\n ),\n './agentcore-gateway/agentcore-gateway.js',\n );\n await addStarExport(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n 'gateways',\n 'index.ts',\n ),\n `./${options.gatewayNameKebabCase}/${options.gatewayNameKebabCase}.js`,\n );\n await addStarExport(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n 'index.ts',\n ),\n './gateways/index.js',\n );\n\n // The gateway construct renders Cedar policies with ejs and its readiness\n // probe uses the AgentCore SDK client; declare both so the lint passes.\n addDependenciesToPackageJson(\n tree,\n withVersions(\n forDependencies<typeof AGENT_CORE_CONSTRUCTS_DEPENDENCIES>(declaration),\n ['ejs', '@aws-sdk/client-bedrock-agentcore'],\n ),\n withVersions(\n forDependencies<typeof AGENT_CORE_CONSTRUCTS_DEPENDENCIES>(declaration),\n ['@types/ejs'],\n ),\n joinPathFragments(PACKAGES_DIR, SHARED_CONSTRUCTS_DIR, 'package.json'),\n );\n};\n\nconst addAgentCoreGatewayTerraformInfra = (\n tree: Tree,\n options: AddAgentCoreGatewayInfraProps,\n) => {\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'terraform',\n 'core',\n 'agentcore-gateway',\n ),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_TERRAFORM_DIR,\n 'src',\n 'core',\n 'agentcore-gateway',\n ),\n { ...terraformProviderVersions() },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'terraform',\n 'app',\n 'agentcore-gateway',\n ),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_TERRAFORM_DIR,\n 'src',\n 'app',\n 'gateways',\n ),\n {\n nameClassName: options.gatewayNameClassName,\n nameKebabCase: options.gatewayNameKebabCase,\n projectDirectory: options.projectDirectory,\n cedarPolicy: options.cedarPolicy,\n auth: options.auth,\n boto3Version: PY_VERSIONS.boto3,\n httpxVersion: PY_VERSIONS.httpx,\n mcpVersion: PY_VERSIONS.mcp,\n ...terraformProviderVersions(),\n },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n // The Cedar render script is only needed when policies are enabled\n if (!options.cedarPolicy) {\n const renderScript = joinPathFragments(\n PACKAGES_DIR,\n SHARED_TERRAFORM_DIR,\n 'src',\n 'app',\n 'gateways',\n options.gatewayNameKebabCase,\n 'render-cedar.cjs',\n );\n if (tree.exists(renderScript)) {\n tree.delete(renderScript);\n }\n }\n};\n"],"names":["generateFiles","joinPathFragments","OverwriteStrategy","updateJson","addStarExport","forDependencies","addDependenciesToPackageJson","esmVars","addDependencyToTargetIfNotPresent","generatedInfrastructure","generatedTerraform","PACKAGES_DIR","SHARED_CONSTRUCTS_DIR","SHARED_TERRAFORM_DIR","PY_VERSIONS","terraformProviderVersions","withVersions","AGENT_CORE_CONSTRUCTS_DEPENDENCIES","name","when","AGENT_CORE_CONSTRUCTS_PY_DEPENDENCIES","addAgentCoreInfra","tree","options","iac","addAgentCoreCDKInfra","addAgentCoreTerraformInfra","config","projectName","dirname","appDirectory","overwriteStrategy","KeepExisting","nameKebabCase","containers","boto3Version","boto3","addMcpServerInfra","nameClassName","mcpServerNameClassName","mcpServerNameKebabCase","dockerImageTag","dockerOutputDir","serverProtocol","auth","session","addAgentInfra","agentNameClassName","agentNameKebabCase","addAgentCoreGatewayInfra","declaration","addAgentCoreGatewayCDKInfra","addAgentCoreGatewayTerraformInfra","gatewayNameClassName","gatewayNameKebabCase","projectDirectory","cedarPolicy","httpxVersion","httpx","mcpVersion","mcp","renderScript","exists","delete"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/utils/agent-core-constructs/agent-core-constructs.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n generateFiles,\n joinPathFragments,\n OverwriteStrategy,\n type ProjectConfiguration,\n type Tree,\n updateJson,\n} from '@nx/devkit';\nimport { addStarExport } from '../ast';\nimport type { Containers } from '../containers';\nimport {\n type DeclaredPyDependency,\n type DeclaredTsDependency,\n type DependencyDeclaration,\n forDependencies,\n type MustDeclare,\n} from '../declared-dependencies';\nimport { addDependenciesToPackageJson } from '../dependencies';\nimport type { Iac } from '../iac';\nimport { esmVars } from '../module-format';\nimport { addDependencyToTargetIfNotPresent } from '../nx';\nimport {\n generatedInfrastructure,\n generatedTerraform,\n type IacMetadata,\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n SHARED_TERRAFORM_DIR,\n} from '../shared-constructs-constants';\nimport {\n type IPyDepVersion,\n type ITsDepVersion,\n PY_VERSIONS,\n terraformProviderVersions,\n withVersions,\n} from '../versions';\n\ntype IACProvider = { iac: Iac };\n\n/**\n * Dependencies a caller must declare to add an AgentCore Gateway construct.\n *\n * Gated on infrastructure having been generated, since the construct helpers only\n * run on that branch.\n */\nexport const AGENT_CORE_CONSTRUCTS_DEPENDENCIES = [\n { name: 'ejs', when: generatedInfrastructure },\n { name: '@aws-sdk/client-bedrock-agentcore', when: generatedInfrastructure },\n { name: '@types/ejs', when: generatedInfrastructure },\n] as const satisfies readonly DeclaredTsDependency<\n ITsDepVersion,\n IacMetadata\n>[];\n\n/**\n * Python versions the generated Terraform pins in an inline `uv run --with`\n * script, rather than in any `pyproject.toml`.\n *\n * Spread through `ownedElsewhere` because nothing installs them into the\n * workspace — the pin is owned so the version sync keeps it current, and gated on\n * Terraform since the CDK branch writes no such script.\n */\nexport const AGENT_CORE_CONSTRUCTS_PY_DEPENDENCIES = [\n { name: 'boto3', when: generatedTerraform },\n { name: 'httpx', when: generatedTerraform },\n { name: 'mcp', when: generatedTerraform },\n] as const satisfies readonly DeclaredPyDependency<\n IPyDepVersion,\n IacMetadata\n>[];\n\nexport type AgentCoreAuth = 'iam' | 'cognito';\n\nexport type AgentCoreSession = 's3' | 'in-memory';\n\nexport interface AddAgentCoreInfraProps {\n nameClassName: string;\n nameKebabCase: string;\n projectName: string;\n dockerImageTag: string;\n dockerOutputDir: string;\n appDirectory: string;\n serverProtocol: 'mcp' | 'http' | 'a2a';\n auth: AgentCoreAuth;\n /** How this runtime's session should be persisted. MCP servers have no session, so pass 'in-memory'. */\n session: AgentCoreSession;\n containers: Containers;\n}\n\nconst addAgentCoreInfra = async (\n tree: Tree,\n options: AddAgentCoreInfraProps & { iac: Iac },\n) => {\n switch (options.iac) {\n case 'cdk':\n await addAgentCoreCDKInfra(tree, options);\n break;\n case 'terraform':\n addAgentCoreTerraformInfra(tree, options);\n break;\n }\n\n // Update shared constructs/terraform project configuration to depend on this project\n updateJson(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n options.iac === 'cdk' ? SHARED_CONSTRUCTS_DIR : SHARED_TERRAFORM_DIR,\n 'project.json',\n ),\n (config: ProjectConfiguration) => {\n addDependencyToTargetIfNotPresent(\n config,\n 'build',\n `${options.projectName}:build`,\n );\n return config;\n },\n );\n};\n\nconst addAgentCoreCDKInfra = async (\n tree: Tree,\n options: AddAgentCoreInfraProps,\n) => {\n // Generate app specific CDK construct\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'cdk', 'app', 'agent-core'),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n options.appDirectory,\n ),\n { ...options, ...esmVars(tree) },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n // Export app specific CDK construct\n await addStarExport(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n options.appDirectory,\n 'index.ts',\n ),\n `./${options.nameKebabCase}/${options.nameKebabCase}.js`,\n );\n await addStarExport(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n 'index.ts',\n ),\n `./${options.appDirectory}/index.js`,\n );\n};\n\nconst addAgentCoreTerraformInfra = (\n tree: Tree,\n options: AddAgentCoreInfraProps,\n) => {\n // Add the AgentCore shared module\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'terraform',\n 'core',\n 'agent-core',\n ),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_TERRAFORM_DIR,\n 'src',\n 'core',\n 'agent-core',\n ),\n {\n containers: options.containers,\n boto3Version: PY_VERSIONS.boto3,\n ...terraformProviderVersions(),\n },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n // Generate app specific agent core configuration\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'terraform',\n 'app',\n 'agent-core',\n ),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_TERRAFORM_DIR,\n 'src',\n 'app',\n options.appDirectory,\n ),\n { ...options, ...terraformProviderVersions() },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n};\n\nexport interface AddMcpServerInfraProps {\n mcpServerNameClassName: string;\n mcpServerNameKebabCase: string;\n projectName: string;\n dockerImageTag: string;\n dockerOutputDir: string;\n auth: AgentCoreAuth;\n containers: Containers;\n}\n\n/**\n * Add an MCP server CDK construct\n */\nexport const addMcpServerInfra = async (\n tree: Tree,\n options: AddMcpServerInfraProps & IACProvider,\n) => {\n await addAgentCoreInfra(tree, {\n nameClassName: options.mcpServerNameClassName,\n nameKebabCase: options.mcpServerNameKebabCase,\n dockerImageTag: options.dockerImageTag,\n dockerOutputDir: options.dockerOutputDir,\n projectName: options.projectName,\n appDirectory: 'mcp-servers',\n serverProtocol: 'mcp',\n iac: options.iac,\n auth: options.auth,\n // MCP servers are stateless (no conversation session to persist).\n session: 'in-memory',\n containers: options.containers,\n });\n};\n\nexport interface AddAgentInfraProps {\n agentNameClassName: string;\n agentNameKebabCase: string;\n projectName: string;\n dockerImageTag: string;\n dockerOutputDir: string;\n auth: AgentCoreAuth;\n session: AgentCoreSession;\n serverProtocol?: 'http' | 'a2a';\n containers: Containers;\n}\n\n/**\n * Add an agent CDK construct\n */\nexport const addAgentInfra = async (\n tree: Tree,\n options: AddAgentInfraProps & IACProvider,\n) => {\n await addAgentCoreInfra(tree, {\n nameClassName: options.agentNameClassName,\n nameKebabCase: options.agentNameKebabCase,\n projectName: options.projectName,\n dockerImageTag: options.dockerImageTag,\n dockerOutputDir: options.dockerOutputDir,\n appDirectory: 'agents',\n session: options.session,\n serverProtocol: options.serverProtocol ?? 'http',\n iac: options.iac,\n auth: options.auth,\n containers: options.containers,\n });\n};\n\nexport interface AddAgentCoreGatewayInfraProps {\n gatewayNameClassName: string;\n gatewayNameKebabCase: string;\n projectName: string;\n projectDirectory: string;\n cedarPolicy: boolean;\n auth: AgentCoreAuth;\n /**\n * The gateway's protocol: mcp aggregates MCP server targets, http proxies\n * agent runtime targets via path-based routing.\n */\n protocol: 'mcp' | 'http';\n}\n\nexport const addAgentCoreGatewayInfra = async <\n const D extends DependencyDeclaration,\n>(\n tree: Tree,\n options: AddAgentCoreGatewayInfraProps & IACProvider,\n declaration: D & MustDeclare<typeof AGENT_CORE_CONSTRUCTS_DEPENDENCIES, D>,\n) => {\n switch (options.iac) {\n case 'cdk':\n await addAgentCoreGatewayCDKInfra(tree, options, declaration);\n break;\n case 'terraform':\n addAgentCoreGatewayTerraformInfra(tree, options);\n break;\n }\n\n updateJson(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n options.iac === 'cdk' ? SHARED_CONSTRUCTS_DIR : SHARED_TERRAFORM_DIR,\n 'project.json',\n ),\n (config: ProjectConfiguration) => {\n addDependencyToTargetIfNotPresent(\n config,\n 'build',\n `${options.projectName}:build`,\n );\n return config;\n },\n );\n};\n\nconst addAgentCoreGatewayCDKInfra = async (\n tree: Tree,\n options: AddAgentCoreGatewayInfraProps,\n declaration: DependencyDeclaration,\n) => {\n // Generic gateway construct (readiness probe, policy engine, Cedar policy\n // loading) shared by all gateways\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'cdk',\n 'core',\n 'agentcore-gateway',\n ),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'core',\n 'agentcore-gateway',\n ),\n { ...esmVars(tree) },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'cdk',\n 'app',\n 'agentcore-gateway',\n ),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n 'gateways',\n ),\n {\n nameClassName: options.gatewayNameClassName,\n nameKebabCase: options.gatewayNameKebabCase,\n projectDirectory: options.projectDirectory,\n cedarPolicy: options.cedarPolicy,\n auth: options.auth,\n protocol: options.protocol,\n ...esmVars(tree),\n },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n await addStarExport(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'core',\n 'index.ts',\n ),\n './agentcore-gateway/agentcore-gateway.js',\n );\n await addStarExport(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n 'gateways',\n 'index.ts',\n ),\n `./${options.gatewayNameKebabCase}/${options.gatewayNameKebabCase}.js`,\n );\n await addStarExport(\n tree,\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n 'index.ts',\n ),\n './gateways/index.js',\n );\n\n // The gateway construct renders Cedar policies with ejs and its readiness\n // probe uses the AgentCore SDK client; declare both so the lint passes.\n addDependenciesToPackageJson(\n tree,\n withVersions(\n forDependencies<typeof AGENT_CORE_CONSTRUCTS_DEPENDENCIES>(declaration),\n ['ejs', '@aws-sdk/client-bedrock-agentcore'],\n ),\n withVersions(\n forDependencies<typeof AGENT_CORE_CONSTRUCTS_DEPENDENCIES>(declaration),\n ['@types/ejs'],\n ),\n joinPathFragments(PACKAGES_DIR, SHARED_CONSTRUCTS_DIR, 'package.json'),\n );\n};\n\nconst addAgentCoreGatewayTerraformInfra = (\n tree: Tree,\n options: AddAgentCoreGatewayInfraProps,\n) => {\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'terraform',\n 'core',\n 'agentcore-gateway',\n ),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_TERRAFORM_DIR,\n 'src',\n 'core',\n 'agentcore-gateway',\n ),\n { ...terraformProviderVersions() },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'terraform',\n 'app',\n 'agentcore-gateway',\n ),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_TERRAFORM_DIR,\n 'src',\n 'app',\n 'gateways',\n ),\n {\n nameClassName: options.gatewayNameClassName,\n nameKebabCase: options.gatewayNameKebabCase,\n projectDirectory: options.projectDirectory,\n cedarPolicy: options.cedarPolicy,\n auth: options.auth,\n protocol: options.protocol,\n boto3Version: PY_VERSIONS.boto3,\n httpxVersion: PY_VERSIONS.httpx,\n mcpVersion: PY_VERSIONS.mcp,\n ...terraformProviderVersions(),\n },\n {\n overwriteStrategy: OverwriteStrategy.KeepExisting,\n },\n );\n\n // The Cedar render script is only needed when policies are enabled\n if (!options.cedarPolicy) {\n const renderScript = joinPathFragments(\n PACKAGES_DIR,\n SHARED_TERRAFORM_DIR,\n 'src',\n 'app',\n 'gateways',\n options.gatewayNameKebabCase,\n 'render-cedar.cjs',\n );\n if (tree.exists(renderScript)) {\n tree.delete(renderScript);\n }\n }\n};\n"],"names":["generateFiles","joinPathFragments","OverwriteStrategy","updateJson","addStarExport","forDependencies","addDependenciesToPackageJson","esmVars","addDependencyToTargetIfNotPresent","generatedInfrastructure","generatedTerraform","PACKAGES_DIR","SHARED_CONSTRUCTS_DIR","SHARED_TERRAFORM_DIR","PY_VERSIONS","terraformProviderVersions","withVersions","AGENT_CORE_CONSTRUCTS_DEPENDENCIES","name","when","AGENT_CORE_CONSTRUCTS_PY_DEPENDENCIES","addAgentCoreInfra","tree","options","iac","addAgentCoreCDKInfra","addAgentCoreTerraformInfra","config","projectName","dirname","appDirectory","overwriteStrategy","KeepExisting","nameKebabCase","containers","boto3Version","boto3","addMcpServerInfra","nameClassName","mcpServerNameClassName","mcpServerNameKebabCase","dockerImageTag","dockerOutputDir","serverProtocol","auth","session","addAgentInfra","agentNameClassName","agentNameKebabCase","addAgentCoreGatewayInfra","declaration","addAgentCoreGatewayCDKInfra","addAgentCoreGatewayTerraformInfra","gatewayNameClassName","gatewayNameKebabCase","projectDirectory","cedarPolicy","protocol","httpxVersion","httpx","mcpVersion","mcp","renderScript","exists","delete"],"mappings":"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"}
|
|
@@ -66,6 +66,9 @@ export class <%- nameClassName %> extends Construct implements IGrantable, IConn
|
|
|
66
66
|
<%_ if (serverProtocol === 'mcp') { _%>
|
|
67
67
|
/** Default Gateway target name for this MCP server. */
|
|
68
68
|
public readonly mcpServerName = '<%- nameKebabCase %>';
|
|
69
|
+
<%_ } else { _%>
|
|
70
|
+
/** Default Gateway target name for this agent. */
|
|
71
|
+
public readonly agentName = '<%- nameKebabCase %>';
|
|
69
72
|
<%_ } _%>
|
|
70
73
|
|
|
71
74
|
constructor(scope: Construct, id: string, props<%_ if (auth !== 'cognito') { _%>?<%_ } _%>: <%- nameClassName %>Props) {
|
|
@@ -19,7 +19,7 @@ import { findWorkspaceRoot } from '../../../core/workspace<% if (esm) { %>.js<%
|
|
|
19
19
|
<%_ if (auth === 'cognito') { _%>
|
|
20
20
|
export type <%- nameClassName %>Props = Omit<
|
|
21
21
|
AgentCoreGatewayProps,
|
|
22
|
-
<%_ if (cedarPolicy) { _%>'cedarPolicyPath' | <%_ } _%>'authorizer'
|
|
22
|
+
<%_ if (cedarPolicy) { _%>'cedarPolicyPath' | <%_ } _%>'authorizer' | 'protocol'
|
|
23
23
|
> & {
|
|
24
24
|
/**
|
|
25
25
|
* Identity details for Cognito authentication. Callers authenticate with a
|
|
@@ -31,13 +31,13 @@ export type <%- nameClassName %>Props = Omit<
|
|
|
31
31
|
};
|
|
32
32
|
};
|
|
33
33
|
<%_ } else if (cedarPolicy) { _%>
|
|
34
|
-
export type <%- nameClassName %>Props = Omit<AgentCoreGatewayProps, 'cedarPolicyPath'>;
|
|
34
|
+
export type <%- nameClassName %>Props = Omit<AgentCoreGatewayProps, 'cedarPolicyPath' | 'protocol'>;
|
|
35
35
|
<%_ } else { _%>
|
|
36
|
-
export type <%- nameClassName %>Props = AgentCoreGatewayProps
|
|
36
|
+
export type <%- nameClassName %>Props = Omit<AgentCoreGatewayProps, 'protocol'>;
|
|
37
37
|
<%_ } _%>
|
|
38
38
|
|
|
39
39
|
/**
|
|
40
|
-
* AgentCore Gateway wired for MCP protocol with <%- auth === 'cognito' ? 'Cognito (JWT)' : 'IAM' %> inbound auth.
|
|
40
|
+
* AgentCore Gateway wired for <%- protocol === 'http' ? 'HTTP proxying of agent runtime targets' : 'MCP protocol' %> with <%- auth === 'cognito' ? 'Cognito (JWT)' : 'IAM' %> inbound auth.
|
|
41
41
|
<%_ if (cedarPolicy) { _%>
|
|
42
42
|
*
|
|
43
43
|
* Cedar policies are loaded from the gateway project's policies/ directory
|
|
@@ -52,6 +52,7 @@ export class <%- nameClassName %> extends AgentCoreGateway {
|
|
|
52
52
|
<%_ if (auth === 'cognito') { _%>
|
|
53
53
|
const { identity, ...restProps } = props;
|
|
54
54
|
super(scope, id, {
|
|
55
|
+
protocol: '<%- protocol %>',
|
|
55
56
|
<%_ if (cedarPolicy) { _%>
|
|
56
57
|
cedarPolicyPath: path.join(
|
|
57
58
|
findWorkspaceRoot(url.fileURLToPath(new URL(<% if (esm) { %>import.meta.url<% } else { %>require('url').pathToFileURL(__filename).href<% } %>))),
|
|
@@ -66,6 +67,7 @@ export class <%- nameClassName %> extends AgentCoreGateway {
|
|
|
66
67
|
});
|
|
67
68
|
<%_ } else { _%>
|
|
68
69
|
super(scope, id, {
|
|
70
|
+
protocol: '<%- protocol %>',
|
|
69
71
|
<%_ if (cedarPolicy) { _%>
|
|
70
72
|
cedarPolicyPath: path.join(
|
|
71
73
|
findWorkspaceRoot(url.fileURLToPath(new URL(<% if (esm) { %>import.meta.url<% } else { %>require('url').pathToFileURL(__filename).href<% } %>))),
|
|
@@ -42,12 +42,24 @@ export interface AgentCoreGatewayProps {
|
|
|
42
42
|
* @default GatewayAuthorizer.usingAwsIam()
|
|
43
43
|
*/
|
|
44
44
|
readonly authorizer?: agentcore.IGatewayAuthorizerConfig;
|
|
45
|
+
/**
|
|
46
|
+
* The gateway's protocol. An `mcp` gateway aggregates MCP server targets
|
|
47
|
+
* into a single MCP endpoint. An `http` gateway has no protocol type and
|
|
48
|
+
* proxies requests to AgentCore Runtime targets via path-based routing
|
|
49
|
+
* (`/<targetName>/invocations`) — the target type AgentCore only allows on
|
|
50
|
+
* gateways without a protocol type.
|
|
51
|
+
*
|
|
52
|
+
* @default 'mcp'
|
|
53
|
+
*/
|
|
54
|
+
readonly protocol?: 'mcp' | 'http';
|
|
45
55
|
}
|
|
46
56
|
|
|
47
57
|
/**
|
|
48
|
-
* AgentCore Gateway
|
|
49
|
-
* tools under `<targetName>___<toolName>` names
|
|
50
|
-
*
|
|
58
|
+
* AgentCore Gateway. With the default `mcp` protocol it exposes attached MCP
|
|
59
|
+
* servers' tools under `<targetName>___<toolName>` names; with the `http`
|
|
60
|
+
* protocol it proxies AgentCore Runtime targets under
|
|
61
|
+
* `/<targetName>/invocations`. Inbound auth defaults to IAM (SigV4); pass an
|
|
62
|
+
* `authorizer` to use Cognito/JWT instead.
|
|
51
63
|
*/
|
|
52
64
|
export class AgentCoreGateway extends Construct implements iam.IGrantable {
|
|
53
65
|
public readonly gateway: agentcore.Gateway;
|
|
@@ -57,10 +69,13 @@ export class AgentCoreGateway extends Construct implements iam.IGrantable {
|
|
|
57
69
|
private readonly policies: agentcore.CfnPolicy[] = [];
|
|
58
70
|
private targetReadinessProbe?: triggers.TriggerFunction;
|
|
59
71
|
private readonly targetRuntimeArns: string[] = [];
|
|
72
|
+
private readonly protocol: 'mcp' | 'http';
|
|
60
73
|
|
|
61
74
|
constructor(scope: Construct, id: string, props?: AgentCoreGatewayProps) {
|
|
62
75
|
super(scope, id);
|
|
63
76
|
|
|
77
|
+
this.protocol = props?.protocol ?? 'mcp';
|
|
78
|
+
|
|
64
79
|
this.gateway = new agentcore.Gateway(this, 'Gateway', {
|
|
65
80
|
// Cap at 39 chars so the 11-char service suffix keeps the gateway id
|
|
66
81
|
// within its 50-char limit.
|
|
@@ -73,6 +88,15 @@ export class AgentCoreGateway extends Construct implements iam.IGrantable {
|
|
|
73
88
|
props?.authorizer ?? agentcore.GatewayAuthorizer.usingAwsIam(),
|
|
74
89
|
});
|
|
75
90
|
|
|
91
|
+
if (this.protocol === 'http') {
|
|
92
|
+
// AgentCore Runtime targets require a gateway without a protocol type,
|
|
93
|
+
// which the Gateway L2 cannot express — it always renders MCP — so
|
|
94
|
+
// remove the protocol from the underlying CloudFormation resource.
|
|
95
|
+
const cfnGateway = this.gateway.node.defaultChild as agentcore.CfnGateway;
|
|
96
|
+
cfnGateway.addPropertyDeletionOverride('ProtocolType');
|
|
97
|
+
cfnGateway.addPropertyDeletionOverride('ProtocolConfiguration');
|
|
98
|
+
}
|
|
99
|
+
|
|
76
100
|
if (props?.cedarPolicyPath) {
|
|
77
101
|
this.policyEngine = new agentcore.CfnPolicyEngine(this, 'PolicyEngine', {
|
|
78
102
|
name: cdk.Names.uniqueResourceName(this, { maxLength: 48 }),
|
|
@@ -420,6 +444,93 @@ export class AgentCoreGateway extends Construct implements iam.IGrantable {
|
|
|
420
444
|
return target;
|
|
421
445
|
}
|
|
422
446
|
|
|
447
|
+
/**
|
|
448
|
+
* Add an agent runtime construct as a target of this Gateway. Requires the
|
|
449
|
+
* `http` protocol — the gateway proxies requests for the agent under
|
|
450
|
+
* `<gatewayUrl>/<targetName>/invocations`, without protocol translation.
|
|
451
|
+
*
|
|
452
|
+
* The target name defaults to the agent construct's `agentName` (its
|
|
453
|
+
* project's class name in kebab-case, e.g. `MyAgent` -> `my-agent`). It
|
|
454
|
+
* forms the target's invocation path, so renaming it later is a breaking
|
|
455
|
+
* change for consumers.
|
|
456
|
+
*/
|
|
457
|
+
public addAgent(
|
|
458
|
+
agent: Construct & {
|
|
459
|
+
readonly agentCoreRuntime: agentcore.Runtime;
|
|
460
|
+
readonly agentName: string;
|
|
461
|
+
},
|
|
462
|
+
props?: {
|
|
463
|
+
gatewayTargetName?: string;
|
|
464
|
+
},
|
|
465
|
+
): agentcore.CfnGatewayTarget {
|
|
466
|
+
return this.addAgentTarget({
|
|
467
|
+
gatewayTargetName: props?.gatewayTargetName ?? agent.agentName,
|
|
468
|
+
agentRuntimeArn: agent.agentCoreRuntime.agentRuntimeArn,
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* Register an agent runtime ARN as a Gateway target. Prefer
|
|
474
|
+
* {@link addAgent} when the construct is in scope.
|
|
475
|
+
*/
|
|
476
|
+
public addAgentTarget(props: {
|
|
477
|
+
gatewayTargetName: string;
|
|
478
|
+
agentRuntimeArn: string;
|
|
479
|
+
}): agentcore.CfnGatewayTarget {
|
|
480
|
+
if (this.protocol !== 'http') {
|
|
481
|
+
throw new Error(
|
|
482
|
+
`Agent runtime targets require an http-protocol gateway, but this gateway uses '${this.protocol}'.`,
|
|
483
|
+
);
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
// The construct id is derived from the target name so the two change
|
|
487
|
+
// together — target names are unique per gateway, and replacing a target
|
|
488
|
+
// under an unchanged name fails with AlreadyExists.
|
|
489
|
+
const target = new agentcore.CfnGatewayTarget(
|
|
490
|
+
this,
|
|
491
|
+
`Target-${props.gatewayTargetName}`,
|
|
492
|
+
{
|
|
493
|
+
gatewayIdentifier: this.gateway.gatewayId,
|
|
494
|
+
name: props.gatewayTargetName,
|
|
495
|
+
targetConfiguration: {
|
|
496
|
+
http: {
|
|
497
|
+
agentcoreRuntime: {
|
|
498
|
+
arn: props.agentRuntimeArn,
|
|
499
|
+
qualifier: 'DEFAULT',
|
|
500
|
+
},
|
|
501
|
+
},
|
|
502
|
+
},
|
|
503
|
+
// The bare gateway IAM role credential: runtime targets reject the
|
|
504
|
+
// iamCredentialProvider detail MCP targets carry.
|
|
505
|
+
credentialProviderConfigurations: [
|
|
506
|
+
{
|
|
507
|
+
credentialProviderType: 'GATEWAY_IAM_ROLE',
|
|
508
|
+
},
|
|
509
|
+
],
|
|
510
|
+
},
|
|
511
|
+
);
|
|
512
|
+
|
|
513
|
+
// Grant the gateway role invoke access to the target runtime before the
|
|
514
|
+
// target is created — AgentCore validates access to the runtime during
|
|
515
|
+
// target creation.
|
|
516
|
+
const grant = this.gateway.role.addToPrincipalPolicy(
|
|
517
|
+
new iam.PolicyStatement({
|
|
518
|
+
actions: [
|
|
519
|
+
'bedrock-agentcore:InvokeAgentRuntime',
|
|
520
|
+
'bedrock-agentcore:InvokeAgentRuntimeWithWebSocketStream',
|
|
521
|
+
// A2A targets additionally serve their agent card via the gateway.
|
|
522
|
+
'bedrock-agentcore:GetAgentCard',
|
|
523
|
+
],
|
|
524
|
+
resources: [props.agentRuntimeArn, `${props.agentRuntimeArn}/*`],
|
|
525
|
+
}),
|
|
526
|
+
);
|
|
527
|
+
if (grant.policyDependable) {
|
|
528
|
+
target.node.addDependency(grant.policyDependable);
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
return target;
|
|
532
|
+
}
|
|
533
|
+
|
|
423
534
|
/**
|
|
424
535
|
* Create a Gateway target for an MCP endpoint, with outbound calls signed
|
|
425
536
|
* using this gateway's own execution role.
|
|
@@ -428,6 +539,11 @@ export class AgentCoreGateway extends Construct implements iam.IGrantable {
|
|
|
428
539
|
gatewayTargetName: string,
|
|
429
540
|
endpoint: string,
|
|
430
541
|
): agentcore.CfnGatewayTarget {
|
|
542
|
+
if (this.protocol !== 'mcp') {
|
|
543
|
+
throw new Error(
|
|
544
|
+
`MCP targets require an mcp-protocol gateway, but this gateway uses '${this.protocol}'.`,
|
|
545
|
+
);
|
|
546
|
+
}
|
|
431
547
|
// The construct id is derived from the target name so the two change
|
|
432
548
|
// together — target names are unique per gateway, and replacing a target
|
|
433
549
|
// under an unchanged name fails with AlreadyExists.
|
|
@@ -33,11 +33,13 @@ variable "additional_iam_policy_statements" {
|
|
|
33
33
|
default = []
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
<%_ if (protocol === 'mcp') { _%>
|
|
36
37
|
variable "tool_dependencies" {
|
|
37
38
|
description = "Target ids whose tools must be queryable before `gateway_url` is consumable. Set this to the gateway's own target ids (e.g. from agentcore-gateway#mcp-connection) when another gateway aggregates this one: the readiness probe waits until this gateway serves those tools, since a parent gateway fetches them at target creation."
|
|
38
39
|
type = list(string)
|
|
39
40
|
default = []
|
|
40
41
|
}
|
|
42
|
+
<%_ } _%>
|
|
41
43
|
|
|
42
44
|
variable "enable_waf" {
|
|
43
45
|
description = "Associate a regional WAFv2 web ACL (default AWS managed rule groups) with the gateway to inspect inbound requests."
|
|
@@ -183,6 +185,7 @@ resource "aws_bedrockagentcore_gateway" "this" {
|
|
|
183
185
|
description = "AgentCore Gateway for <%- nameClassName %>"
|
|
184
186
|
role_arn = aws_iam_role.gateway_role.arn
|
|
185
187
|
|
|
188
|
+
<%_ if (protocol === 'mcp') { _%>
|
|
186
189
|
protocol_type = "MCP"
|
|
187
190
|
protocol_configuration {
|
|
188
191
|
mcp {
|
|
@@ -190,6 +193,11 @@ resource "aws_bedrockagentcore_gateway" "this" {
|
|
|
190
193
|
supported_versions = ["2025-03-26"]
|
|
191
194
|
}
|
|
192
195
|
}
|
|
196
|
+
<%_ } else { _%>
|
|
197
|
+
# No protocol type: AgentCore Runtime targets require a gateway without one.
|
|
198
|
+
# The gateway proxies requests to its runtime targets via path-based routing
|
|
199
|
+
# (`/<targetName>/invocations`).
|
|
200
|
+
<%_ } _%>
|
|
193
201
|
|
|
194
202
|
authorizer_type = "<%- auth === 'cognito' ? 'CUSTOM_JWT' : 'AWS_IAM' %>"
|
|
195
203
|
<%_ if (auth === 'cognito') { _%>
|
|
@@ -364,6 +372,7 @@ resource "aws_bedrockagentcore_policy" "policies" {
|
|
|
364
372
|
}
|
|
365
373
|
<%_ } _%>
|
|
366
374
|
|
|
375
|
+
<%_ if (protocol === 'mcp') { _%>
|
|
367
376
|
# A parent gateway fetches this gateway's tools when it registers it as a
|
|
368
377
|
# target, so this gateway must already serve them — its own targets register
|
|
369
378
|
# their tools asynchronously after creation. Probe `tools/list` over SigV4
|
|
@@ -448,6 +457,7 @@ print(f'Gateway {gateway_url} is serving tools')
|
|
|
448
457
|
}
|
|
449
458
|
}
|
|
450
459
|
}
|
|
460
|
+
<%_ } _%>
|
|
451
461
|
|
|
452
462
|
# Add gateway URL to runtime config
|
|
453
463
|
module "add_gateway_url_to_runtime_config" {
|
|
@@ -470,12 +480,19 @@ output "gateway_arn" {
|
|
|
470
480
|
value = aws_bedrockagentcore_gateway.this.gateway_arn
|
|
471
481
|
}
|
|
472
482
|
|
|
483
|
+
<%_ if (protocol === 'mcp') { _%>
|
|
473
484
|
output "gateway_url" {
|
|
474
485
|
description = "MCP endpoint URL of the Bedrock AgentCore Gateway. When `tool_dependencies` is set, this value flows through the readiness probe so consumers (e.g. a parent gateway target) wait until the gateway serves its aggregated tools."
|
|
475
486
|
value = length(var.tool_dependencies) > 0 ? (
|
|
476
487
|
null_resource.gateway_ready[0].triggers.gateway_url
|
|
477
488
|
) : aws_bedrockagentcore_gateway.this.gateway_url
|
|
478
489
|
}
|
|
490
|
+
<%_ } else { _%>
|
|
491
|
+
output "gateway_url" {
|
|
492
|
+
description = "Endpoint URL of the Bedrock AgentCore Gateway. Runtime targets are served under `<gateway_url minus /mcp>/<targetName>/invocations`."
|
|
493
|
+
value = aws_bedrockagentcore_gateway.this.gateway_url
|
|
494
|
+
}
|
|
495
|
+
<%_ } _%>
|
|
479
496
|
|
|
480
497
|
output "gateway_role_arn" {
|
|
481
498
|
description = "ARN of the IAM role assumed by the gateway service"
|
|
@@ -16,6 +16,11 @@ export declare const ensureAwsNxPluginConfig: (tree: Tree) => Promise<AwsNxPlugi
|
|
|
16
16
|
* resolution — imports from @aws/nx-plugin/* resolve via alias, and any
|
|
17
17
|
* third-party imports resolve from the workspace's node_modules. Synchronous,
|
|
18
18
|
* since `jiti.evalModule` runs in-memory.
|
|
19
|
+
*
|
|
20
|
+
* The on-disk transform cache is off: jiti keys it by file path, but the source
|
|
21
|
+
* here comes from the Tree, so one path holds different content as generators
|
|
22
|
+
* mutate the config — and every test Tree shares the `/virtual` root, making
|
|
23
|
+
* concurrent workers collide on a single cache file.
|
|
19
24
|
*/
|
|
20
25
|
export declare const readAwsNxPluginConfig: (tree: Tree) => AwsNxPluginConfig | undefined;
|
|
21
26
|
/**
|
|
@@ -32,6 +32,11 @@ export const AWS_NX_PLUGIN_CONFIG_FILE_NAME = 'aws-nx-plugin.config.mts';
|
|
|
32
32
|
* resolution — imports from @aws/nx-plugin/* resolve via alias, and any
|
|
33
33
|
* third-party imports resolve from the workspace's node_modules. Synchronous,
|
|
34
34
|
* since `jiti.evalModule` runs in-memory.
|
|
35
|
+
*
|
|
36
|
+
* The on-disk transform cache is off: jiti keys it by file path, but the source
|
|
37
|
+
* here comes from the Tree, so one path holds different content as generators
|
|
38
|
+
* mutate the config — and every test Tree shares the `/virtual` root, making
|
|
39
|
+
* concurrent workers collide on a single cache file.
|
|
35
40
|
*/ export const readAwsNxPluginConfig = (tree)=>{
|
|
36
41
|
if (!tree.exists(AWS_NX_PLUGIN_CONFIG_FILE_NAME)) {
|
|
37
42
|
return undefined;
|
|
@@ -39,7 +44,8 @@ export const AWS_NX_PLUGIN_CONFIG_FILE_NAME = 'aws-nx-plugin.config.mts';
|
|
|
39
44
|
const source = tree.read(AWS_NX_PLUGIN_CONFIG_FILE_NAME, 'utf-8');
|
|
40
45
|
const configFilePath = join(tree.root, AWS_NX_PLUGIN_CONFIG_FILE_NAME);
|
|
41
46
|
const jiti = createJiti(import.meta.filename, {
|
|
42
|
-
alias: AWS_NX_PLUGIN_JITI_ALIASES
|
|
47
|
+
alias: AWS_NX_PLUGIN_JITI_ALIASES,
|
|
48
|
+
fsCache: false
|
|
43
49
|
});
|
|
44
50
|
const mod = jiti.evalModule(source, {
|
|
45
51
|
filename: configFilePath
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/utils/config/utils.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport { generateFiles, joinPathFragments, type Tree } from '@nx/devkit';\nimport { existsSync, readFileSync } from 'fs';\nimport { createJiti } from 'jiti';\nimport { join } from 'path';\nimport { applyGritQL, matchGritQL } from '../ast';\nimport { formatFilesInSubtree } from '../format';\nimport type { AwsNxPluginConfig } from '.';\n\nexport const AWS_NX_PLUGIN_CONFIG_FILE_NAME = 'aws-nx-plugin.config.mts';\n\n/**\n * Aliases used by jiti to resolve `@aws/nx-plugin` imports in the config file\n * to this package's source, so the config can be evaluated in-memory.\n */\nconst AWS_NX_PLUGIN_JITI_ALIASES = {\n '@aws/nx-plugin/sdk/license': join(\n import.meta.dirname,\n '..',\n '..',\n 'sdk',\n 'license',\n ),\n '@aws/nx-plugin': join(import.meta.dirname, '..', '..'),\n};\n\n/**\n * Ensure that the config file exists\n */\nexport const ensureAwsNxPluginConfig = async (\n tree: Tree,\n): Promise<AwsNxPluginConfig> => {\n if (!tree.exists(AWS_NX_PLUGIN_CONFIG_FILE_NAME)) {\n // Create an empty config file if it doesn't already exist\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files'),\n '.',\n {},\n );\n }\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return readAwsNxPluginConfig(tree)!;\n};\n\n/**\n * Read config from the aws nx plugin configuration file.\n *\n * Uses jiti to evaluate the TypeScript source in-memory with proper module\n * resolution — imports from @aws/nx-plugin/* resolve via alias, and any\n * third-party imports resolve from the workspace's node_modules. Synchronous,\n * since `jiti.evalModule` runs in-memory.\n */\nexport const readAwsNxPluginConfig = (\n tree: Tree,\n): AwsNxPluginConfig | undefined => {\n if (!tree.exists(AWS_NX_PLUGIN_CONFIG_FILE_NAME)) {\n return undefined;\n }\n const source = tree.read(AWS_NX_PLUGIN_CONFIG_FILE_NAME, 'utf-8')!;\n const configFilePath = join(tree.root, AWS_NX_PLUGIN_CONFIG_FILE_NAME);\n\n const jiti = createJiti(import.meta.filename, {\n alias: AWS_NX_PLUGIN_JITI_ALIASES,\n });\n\n const mod = jiti.evalModule(source, { filename: configFilePath });\n return (mod as any).default ?? mod;\n};\n\n/**\n * Read config directly from disk. Used by executors that run in the real\n * workspace (not a virtual Tree). Resolves all imports — including\n * third-party dependencies — from the workspace's node_modules.\n */\nexport const readAwsNxPluginConfigFromDisk = (\n workspaceRoot: string,\n): AwsNxPluginConfig | undefined => {\n const configPath = join(workspaceRoot, AWS_NX_PLUGIN_CONFIG_FILE_NAME);\n if (!existsSync(configPath)) return undefined;\n\n const source = readFileSync(configPath, 'utf-8');\n\n const jiti = createJiti(import.meta.filename, {\n alias: AWS_NX_PLUGIN_JITI_ALIASES,\n });\n const mod = jiti.evalModule(source, { filename: configPath });\n return (mod as any).default ?? mod;\n};\n\nconst PLACEHOLDER = '\"__PLACEHOLDER__\"';\n\n/**\n * Use GritQL to set a top-level property in the export default object,\n * then substitute the placeholder with the JSON-serialized value.\n * Preserves all other properties (including JS expressions) untouched.\n */\nconst setConfigProperty = async (\n tree: Tree,\n filePath: string,\n key: string,\n value: unknown,\n): Promise<void> => {\n const json = JSON.stringify(value);\n\n // Check if the property already exists using a named metavariable\n // to avoid ambiguity with anonymous $_ in nested where clauses\n const existsInSatisfies = await matchGritQL(\n tree,\n filePath,\n `\\`${key}: $val\\` where { $val <: within \\`export default $_ satisfies $_\\` }`,\n );\n const existsInPlain =\n !existsInSatisfies &&\n (await matchGritQL(\n tree,\n filePath,\n `\\`${key}: $val\\` where { $val <: within \\`export default $_\\` }`,\n ));\n\n if (existsInSatisfies || existsInPlain) {\n // Replace only this property's value, scoped to the export default\n const within = existsInSatisfies\n ? `within \\`export default $_ satisfies $_\\``\n : `within \\`export default $_\\``;\n await applyGritQL(\n tree,\n filePath,\n `\\`${key}: $old\\` => \\`${key}: ${PLACEHOLDER}\\` where { $old <: ${within} }`,\n );\n } else {\n // Add the new property using GritQL's += (accumulate) operator.\n // For non-empty objects, += appends correctly without double commas.\n // For empty objects, += fails so we fall back to a direct replacement.\n let added = await applyGritQL(\n tree,\n filePath,\n `\\`export default { $props } satisfies $type\\` where { $props += \\`, ${key}: ${PLACEHOLDER}\\` }`,\n );\n\n if (!added) {\n added = await applyGritQL(\n tree,\n filePath,\n `\\`export default { } satisfies $type\\` => \\`export default { ${key}: ${PLACEHOLDER} } satisfies $type\\``,\n );\n }\n\n if (!added) {\n added = await applyGritQL(\n tree,\n filePath,\n `\\`export default { $props }\\` where { $props += \\`, ${key}: ${PLACEHOLDER}\\` }`,\n );\n }\n\n if (!added) {\n await applyGritQL(\n tree,\n filePath,\n `\\`export default { }\\` => \\`export default { ${key}: ${PLACEHOLDER} }\\``,\n );\n }\n }\n\n // Substitute the placeholder with the actual JSON value\n const content = tree.read(filePath)!.toString();\n tree.write(filePath, content.replace(PLACEHOLDER, json));\n};\n\n/**\n * Update the aws nx plugin config file.\n * Only the specified top-level keys are replaced; all other properties\n * (including those containing JS expressions) are left untouched in source.\n */\nexport const updateAwsNxPluginConfig = async (\n tree: Tree,\n configUpdate: Partial<AwsNxPluginConfig>,\n): Promise<void> => {\n const filePath = AWS_NX_PLUGIN_CONFIG_FILE_NAME;\n\n for (const [key, value] of Object.entries(configUpdate)) {\n await setConfigProperty(tree, filePath, key, value);\n }\n\n // Prettier formats the result into properly indented TypeScript\n await formatFilesInSubtree(tree, filePath);\n};\n"],"names":["generateFiles","joinPathFragments","existsSync","readFileSync","createJiti","join","applyGritQL","matchGritQL","formatFilesInSubtree","AWS_NX_PLUGIN_CONFIG_FILE_NAME","AWS_NX_PLUGIN_JITI_ALIASES","dirname","ensureAwsNxPluginConfig","tree","exists","readAwsNxPluginConfig","undefined","source","read","configFilePath","root","jiti","filename","alias","mod","evalModule","default","readAwsNxPluginConfigFromDisk","workspaceRoot","configPath","PLACEHOLDER","setConfigProperty","filePath","key","value","json","JSON","stringify","existsInSatisfies","existsInPlain","within","added","content","toString","write","replace","updateAwsNxPluginConfig","configUpdate","Object","entries"],"mappings":"AAAA;;;CAGC,GACD,SAASA,aAAa,EAAEC,iBAAiB,QAAmB,aAAa;AACzE,SAASC,UAAU,EAAEC,YAAY,QAAQ,KAAK;AAC9C,SAASC,UAAU,QAAQ,OAAO;AAClC,SAASC,IAAI,QAAQ,OAAO;AAC5B,SAASC,WAAW,EAAEC,WAAW,QAAQ,YAAS;AAClD,SAASC,oBAAoB,QAAQ,eAAY;AAGjD,OAAO,MAAMC,iCAAiC,2BAA2B;AAEzE;;;CAGC,GACD,MAAMC,6BAA6B;IACjC,8BAA8BL,KAC5B,YAAYM,OAAO,EACnB,MACA,MACA,OACA;IAEF,kBAAkBN,KAAK,YAAYM,OAAO,EAAE,MAAM;AACpD;AAEA;;CAEC,GACD,OAAO,MAAMC,0BAA0B,OACrCC;IAEA,IAAI,CAACA,KAAKC,MAAM,CAACL,iCAAiC;QAChD,0DAA0D;QAC1DT,cACEa,MACAZ,kBAAkB,YAAYU,OAAO,EAAE,UACvC,KACA,CAAC;IAEL;IACA,oEAAoE;IACpE,OAAOI,sBAAsBF;AAC/B,EAAE;AAEF
|
|
1
|
+
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/utils/config/utils.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport { generateFiles, joinPathFragments, type Tree } from '@nx/devkit';\nimport { existsSync, readFileSync } from 'fs';\nimport { createJiti } from 'jiti';\nimport { join } from 'path';\nimport { applyGritQL, matchGritQL } from '../ast';\nimport { formatFilesInSubtree } from '../format';\nimport type { AwsNxPluginConfig } from '.';\n\nexport const AWS_NX_PLUGIN_CONFIG_FILE_NAME = 'aws-nx-plugin.config.mts';\n\n/**\n * Aliases used by jiti to resolve `@aws/nx-plugin` imports in the config file\n * to this package's source, so the config can be evaluated in-memory.\n */\nconst AWS_NX_PLUGIN_JITI_ALIASES = {\n '@aws/nx-plugin/sdk/license': join(\n import.meta.dirname,\n '..',\n '..',\n 'sdk',\n 'license',\n ),\n '@aws/nx-plugin': join(import.meta.dirname, '..', '..'),\n};\n\n/**\n * Ensure that the config file exists\n */\nexport const ensureAwsNxPluginConfig = async (\n tree: Tree,\n): Promise<AwsNxPluginConfig> => {\n if (!tree.exists(AWS_NX_PLUGIN_CONFIG_FILE_NAME)) {\n // Create an empty config file if it doesn't already exist\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files'),\n '.',\n {},\n );\n }\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return readAwsNxPluginConfig(tree)!;\n};\n\n/**\n * Read config from the aws nx plugin configuration file.\n *\n * Uses jiti to evaluate the TypeScript source in-memory with proper module\n * resolution — imports from @aws/nx-plugin/* resolve via alias, and any\n * third-party imports resolve from the workspace's node_modules. Synchronous,\n * since `jiti.evalModule` runs in-memory.\n *\n * The on-disk transform cache is off: jiti keys it by file path, but the source\n * here comes from the Tree, so one path holds different content as generators\n * mutate the config — and every test Tree shares the `/virtual` root, making\n * concurrent workers collide on a single cache file.\n */\nexport const readAwsNxPluginConfig = (\n tree: Tree,\n): AwsNxPluginConfig | undefined => {\n if (!tree.exists(AWS_NX_PLUGIN_CONFIG_FILE_NAME)) {\n return undefined;\n }\n const source = tree.read(AWS_NX_PLUGIN_CONFIG_FILE_NAME, 'utf-8')!;\n const configFilePath = join(tree.root, AWS_NX_PLUGIN_CONFIG_FILE_NAME);\n\n const jiti = createJiti(import.meta.filename, {\n alias: AWS_NX_PLUGIN_JITI_ALIASES,\n fsCache: false,\n });\n\n const mod = jiti.evalModule(source, { filename: configFilePath });\n return (mod as any).default ?? mod;\n};\n\n/**\n * Read config directly from disk. Used by executors that run in the real\n * workspace (not a virtual Tree). Resolves all imports — including\n * third-party dependencies — from the workspace's node_modules.\n */\nexport const readAwsNxPluginConfigFromDisk = (\n workspaceRoot: string,\n): AwsNxPluginConfig | undefined => {\n const configPath = join(workspaceRoot, AWS_NX_PLUGIN_CONFIG_FILE_NAME);\n if (!existsSync(configPath)) return undefined;\n\n const source = readFileSync(configPath, 'utf-8');\n\n const jiti = createJiti(import.meta.filename, {\n alias: AWS_NX_PLUGIN_JITI_ALIASES,\n });\n const mod = jiti.evalModule(source, { filename: configPath });\n return (mod as any).default ?? mod;\n};\n\nconst PLACEHOLDER = '\"__PLACEHOLDER__\"';\n\n/**\n * Use GritQL to set a top-level property in the export default object,\n * then substitute the placeholder with the JSON-serialized value.\n * Preserves all other properties (including JS expressions) untouched.\n */\nconst setConfigProperty = async (\n tree: Tree,\n filePath: string,\n key: string,\n value: unknown,\n): Promise<void> => {\n const json = JSON.stringify(value);\n\n // Check if the property already exists using a named metavariable\n // to avoid ambiguity with anonymous $_ in nested where clauses\n const existsInSatisfies = await matchGritQL(\n tree,\n filePath,\n `\\`${key}: $val\\` where { $val <: within \\`export default $_ satisfies $_\\` }`,\n );\n const existsInPlain =\n !existsInSatisfies &&\n (await matchGritQL(\n tree,\n filePath,\n `\\`${key}: $val\\` where { $val <: within \\`export default $_\\` }`,\n ));\n\n if (existsInSatisfies || existsInPlain) {\n // Replace only this property's value, scoped to the export default\n const within = existsInSatisfies\n ? `within \\`export default $_ satisfies $_\\``\n : `within \\`export default $_\\``;\n await applyGritQL(\n tree,\n filePath,\n `\\`${key}: $old\\` => \\`${key}: ${PLACEHOLDER}\\` where { $old <: ${within} }`,\n );\n } else {\n // Add the new property using GritQL's += (accumulate) operator.\n // For non-empty objects, += appends correctly without double commas.\n // For empty objects, += fails so we fall back to a direct replacement.\n let added = await applyGritQL(\n tree,\n filePath,\n `\\`export default { $props } satisfies $type\\` where { $props += \\`, ${key}: ${PLACEHOLDER}\\` }`,\n );\n\n if (!added) {\n added = await applyGritQL(\n tree,\n filePath,\n `\\`export default { } satisfies $type\\` => \\`export default { ${key}: ${PLACEHOLDER} } satisfies $type\\``,\n );\n }\n\n if (!added) {\n added = await applyGritQL(\n tree,\n filePath,\n `\\`export default { $props }\\` where { $props += \\`, ${key}: ${PLACEHOLDER}\\` }`,\n );\n }\n\n if (!added) {\n await applyGritQL(\n tree,\n filePath,\n `\\`export default { }\\` => \\`export default { ${key}: ${PLACEHOLDER} }\\``,\n );\n }\n }\n\n // Substitute the placeholder with the actual JSON value\n const content = tree.read(filePath)!.toString();\n tree.write(filePath, content.replace(PLACEHOLDER, json));\n};\n\n/**\n * Update the aws nx plugin config file.\n * Only the specified top-level keys are replaced; all other properties\n * (including those containing JS expressions) are left untouched in source.\n */\nexport const updateAwsNxPluginConfig = async (\n tree: Tree,\n configUpdate: Partial<AwsNxPluginConfig>,\n): Promise<void> => {\n const filePath = AWS_NX_PLUGIN_CONFIG_FILE_NAME;\n\n for (const [key, value] of Object.entries(configUpdate)) {\n await setConfigProperty(tree, filePath, key, value);\n }\n\n // Prettier formats the result into properly indented TypeScript\n await formatFilesInSubtree(tree, filePath);\n};\n"],"names":["generateFiles","joinPathFragments","existsSync","readFileSync","createJiti","join","applyGritQL","matchGritQL","formatFilesInSubtree","AWS_NX_PLUGIN_CONFIG_FILE_NAME","AWS_NX_PLUGIN_JITI_ALIASES","dirname","ensureAwsNxPluginConfig","tree","exists","readAwsNxPluginConfig","undefined","source","read","configFilePath","root","jiti","filename","alias","fsCache","mod","evalModule","default","readAwsNxPluginConfigFromDisk","workspaceRoot","configPath","PLACEHOLDER","setConfigProperty","filePath","key","value","json","JSON","stringify","existsInSatisfies","existsInPlain","within","added","content","toString","write","replace","updateAwsNxPluginConfig","configUpdate","Object","entries"],"mappings":"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"}
|
package/src/utils/connection/open-api/files/components/__apiNameClassName__Provider.tsx.template
CHANGED
|
@@ -7,7 +7,16 @@ import { useSigV4 } from '../hooks/useSigV4';
|
|
|
7
7
|
<%_ } else if (auth === 'cognito') { _%>
|
|
8
8
|
import { useAuth } from 'react-oidc-context';
|
|
9
9
|
<%_ } _%>
|
|
10
|
-
<%_ if (
|
|
10
|
+
<%_ if (gatewayRoute) { _%>
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Build the agent's base URL from its AgentCore Gateway's URL. The gateway
|
|
14
|
+
* proxies `/<targetName>/...` paths to the agent runtime.
|
|
15
|
+
*/
|
|
16
|
+
function buildGatewayTargetUrl(gatewayUrl: string): string {
|
|
17
|
+
return `${new URL(gatewayUrl).origin}/<%- gatewayRoute.targetName %>`;
|
|
18
|
+
}
|
|
19
|
+
<%_ } else if (isAgentRuntime) { _%>
|
|
11
20
|
|
|
12
21
|
/**
|
|
13
22
|
* Build an HTTP URL from a Bedrock AgentCore Runtime ARN
|
|
@@ -24,7 +33,9 @@ export const <%- apiNameClassName %>ClientContext = createContext<<%- apiNameCla
|
|
|
24
33
|
|
|
25
34
|
const useCreate<%- apiNameClassName %>Client = (): <%- apiNameClassName %> => {
|
|
26
35
|
const runtimeConfig = useRuntimeConfig();
|
|
27
|
-
<%_ if (
|
|
36
|
+
<%_ if (gatewayRoute) { _%>
|
|
37
|
+
const apiUrl = buildGatewayTargetUrl(runtimeConfig.gateways.<%- gatewayRoute.gatewayClassName %>);
|
|
38
|
+
<%_ } else if (isAgentRuntime) { _%>
|
|
28
39
|
const agentRuntimeValue = runtimeConfig.agentRuntimes.<%- apiNameClassName %>;
|
|
29
40
|
// A local-dev override is a plain URL; otherwise it's the agent's runtime
|
|
30
41
|
// ARN, so build the invocation URL from it.
|
|
@@ -59,6 +59,15 @@ export interface AddOpenApiReactClientOptions {
|
|
|
59
59
|
* When false (default), reads from runtimeConfig.apis directly.
|
|
60
60
|
*/
|
|
61
61
|
isAgentRuntime?: boolean;
|
|
62
|
+
/**
|
|
63
|
+
* When set, the generated provider reads the gateway's URL from
|
|
64
|
+
* runtimeConfig.gateways and routes to the agent via the gateway's
|
|
65
|
+
* path-based `/<targetName>` route instead of invoking the runtime directly.
|
|
66
|
+
*/
|
|
67
|
+
gatewayRoute?: {
|
|
68
|
+
gatewayClassName: string;
|
|
69
|
+
targetName: string;
|
|
70
|
+
};
|
|
62
71
|
/**
|
|
63
72
|
* When true, skips the dev target setup. Use this when the caller
|
|
64
73
|
* handles dev target configuration separately (e.g. agent connections
|
|
@@ -69,4 +78,4 @@ export interface AddOpenApiReactClientOptions {
|
|
|
69
78
|
/**
|
|
70
79
|
* Adds an OpenAPI React client to the frontend project along with supporting build targets
|
|
71
80
|
*/
|
|
72
|
-
export declare const addOpenApiReactClient: <const D extends DependencyDeclaration>(tree: Tree, { apiName, frontendProjectConfig, backendProjectConfig, specBuildProject, specPath, specBuildTargetName, auth, port, isAgentRuntime, skipLocalDev, }: AddOpenApiReactClientOptions, declaration: D & MustDeclare<typeof OPEN_API_REACT_DEPENDENCIES, D>) => Promise<void>;
|
|
81
|
+
export declare const addOpenApiReactClient: <const D extends DependencyDeclaration>(tree: Tree, { apiName, frontendProjectConfig, backendProjectConfig, specBuildProject, specPath, specBuildTargetName, auth, port, isAgentRuntime, gatewayRoute, skipLocalDev, }: AddOpenApiReactClientOptions, declaration: D & MustDeclare<typeof OPEN_API_REACT_DEPENDENCIES, D>) => Promise<void>;
|
|
@@ -36,7 +36,7 @@ import { withVersions } from "../../versions.js";
|
|
|
36
36
|
];
|
|
37
37
|
/**
|
|
38
38
|
* Adds an OpenAPI React client to the frontend project along with supporting build targets
|
|
39
|
-
*/ export const addOpenApiReactClient = async (tree, { apiName, frontendProjectConfig, backendProjectConfig, specBuildProject, specPath, specBuildTargetName, auth, port, isAgentRuntime = false, skipLocalDev = false }, declaration)=>{
|
|
39
|
+
*/ export const addOpenApiReactClient = async (tree, { apiName, frontendProjectConfig, backendProjectConfig, specBuildProject, specPath, specBuildTargetName, auth, port, isAgentRuntime = false, gatewayRoute, skipLocalDev = false }, declaration)=>{
|
|
40
40
|
const clientGenTarget = `generate:${kebabCase(apiName)}-client`;
|
|
41
41
|
const clientGenWatchTarget = `watch-${clientGenTarget}`;
|
|
42
42
|
const generatedClientDir = joinPathFragments('generated', kebabCase(apiName));
|
|
@@ -120,7 +120,8 @@ import { withVersions } from "../../versions.js";
|
|
|
120
120
|
apiName,
|
|
121
121
|
apiNameClassName,
|
|
122
122
|
generatedClientDir,
|
|
123
|
-
isAgentRuntime
|
|
123
|
+
isAgentRuntime,
|
|
124
|
+
gatewayRoute
|
|
124
125
|
});
|
|
125
126
|
// Update main.tsx to add required providers
|
|
126
127
|
const mainTsxPath = joinPathFragments(frontendProjectConfig.sourceRoot, 'main.tsx');
|