@aws/nx-plugin 1.0.0-rc.90 → 1.0.0-rc.92
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 +2 -2
- package/migrations.json +32 -27
- package/package.json +4 -4
- package/src/infra/app/__snapshots__/generator.spec.ts.snap +3 -3
- package/src/internal/test-matrix/generator.js +28 -0
- package/src/internal/test-matrix/generator.js.map +1 -1
- package/src/migrations/latest/react-website-unique-dev-ports/metadata.json +3 -0
- package/src/migrations/latest/react-website-unique-dev-ports/migration.js +79 -0
- package/src/migrations/latest/react-website-unique-dev-ports/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.87/0001-add-destroy-sandbox-target/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.87/0002-terraform-rdb-proxy-iam-connect-grant/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.88/0001-python-version-drop-exact-patch/migration.d.ts +6 -0
- package/src/migrations/v1.0.0-rc.88/0001-python-version-drop-exact-patch/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.88/0002-react-website-nx-react-express-override/migration.js.map +1 -0
- package/src/migrations/v1.0.0-rc.89/0001-nx-parallel-default/migration.js.map +1 -0
- package/src/preset/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/py/agent/__snapshots__/generator.constructs.spec.ts.snap +2 -2
- package/src/py/agent/__snapshots__/generator.frameworks.spec.ts.snap +1 -1
- package/src/py/agent/__snapshots__/generator.protocols.spec.ts.snap +91 -116
- package/src/py/agent/files/package/main.py.template +13 -0
- package/src/py/agent/generator.d.ts +6 -1
- package/src/py/agent/generator.js +82 -45
- package/src/py/agent/generator.js.map +1 -1
- package/src/py/agent/schema.d.js.map +1 -1
- package/src/py/agent/schema.d.ts +2 -1
- package/src/py/agent/schema.json +2 -2
- package/src/py/mcp-server/__snapshots__/generator.spec.ts.snap +66 -115
- package/src/py/mcp-server/files/package/main.py.template +13 -0
- package/src/py/mcp-server/generator.d.ts +6 -1
- package/src/py/mcp-server/generator.js +79 -43
- package/src/py/mcp-server/generator.js.map +1 -1
- package/src/py/mcp-server/schema.d.js.map +1 -1
- package/src/py/mcp-server/schema.d.ts +2 -1
- package/src/py/mcp-server/schema.json +2 -2
- package/src/py/rdb/__snapshots__/generator.spec.ts.snap +14 -61
- package/src/ts/agent/__snapshots__/generator.spec.ts.snap +78 -115
- package/src/ts/agent/generator.d.ts +26 -1
- package/src/ts/agent/generator.js +71 -45
- package/src/ts/agent/generator.js.map +1 -1
- package/src/ts/agent/schema.d.js.map +1 -1
- package/src/ts/agent/schema.d.ts +2 -1
- package/src/ts/agent/schema.json +2 -2
- package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +65 -114
- package/src/ts/mcp-server/generator.d.ts +26 -1
- package/src/ts/mcp-server/generator.js +66 -38
- package/src/ts/mcp-server/generator.js.map +1 -1
- package/src/ts/mcp-server/schema.d.js.map +1 -1
- package/src/ts/mcp-server/schema.d.ts +2 -1
- package/src/ts/mcp-server/schema.json +2 -2
- package/src/ts/rdb/__snapshots__/generator.spec.ts.snap +16 -110
- package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +12 -10
- package/src/ts/react-website/app/generator.js +16 -0
- package/src/ts/react-website/app/generator.js.map +1 -1
- package/src/ts/react-website/cognito-auth/__snapshots__/generator.terraform.spec.ts.snap +1 -1
- package/src/ts/react-website/cognito-auth/generator.js +14 -2
- package/src/ts/react-website/cognito-auth/generator.js.map +1 -1
- package/src/utils/agent-core-constructs/agent-core-constructs.d.ts +25 -6
- package/src/utils/agent-core-constructs/agent-core-constructs.js +36 -7
- 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 +20 -4
- package/src/utils/agent-core-constructs/files/terraform/app/agent-core/__nameKebabCase__/__nameKebabCase__.tf.template +34 -1
- package/src/utils/agent-core-constructs/files/terraform/core/agent-core/runtime.tf.template +51 -112
- package/src/utils/agent-core-constructs/files/terraform/core/agent-core-code/runtime.tf.template +204 -0
- package/src/utils/agent-core-constructs/files/terraform/core/agent-core-container/runtime.tf.template +235 -0
- package/src/utils/agent-core-packaging.d.ts +119 -0
- package/src/utils/agent-core-packaging.js +131 -0
- package/src/utils/agent-core-packaging.js.map +1 -0
- package/src/utils/agent-core-runtime-resolution.d.ts +35 -0
- package/src/utils/agent-core-runtime-resolution.js +68 -0
- package/src/utils/agent-core-runtime-resolution.js.map +1 -0
- package/src/utils/files/terraform/src/core/asset-ecr/asset-ecr.tf.template +137 -0
- package/src/utils/identity-constructs/files/cdk/core/user-identity.ts.template +1 -1
- package/src/utils/identity-constructs/files/terraform/core/user-identity/identity/identity.tf.template +1 -4
- package/src/utils/identity-constructs/identity-constructs.d.ts +22 -2
- package/src/utils/identity-constructs/identity-constructs.js +75 -5
- package/src/utils/identity-constructs/identity-constructs.js.map +1 -1
- package/src/utils/port.d.ts +5 -0
- package/src/utils/port.js +1 -1
- package/src/utils/port.js.map +1 -1
- package/src/utils/rdb-constructs/files/terraform/app/dbs/__nameKebabCase__/__nameKebabCase__.tf.template +12 -59
- package/src/utils/versions.d.ts +51 -31
- package/src/utils/versions.js +48 -31
- package/src/utils/versions.js.map +1 -1
- package/src/migrations/latest/add-destroy-sandbox-target/migration.js.map +0 -1
- package/src/migrations/latest/nx-parallel-default/migration.js.map +0 -1
- package/src/migrations/latest/python-version-drop-exact-patch/migration.js.map +0 -1
- package/src/migrations/latest/react-website-nx-react-express-override/migration.js.map +0 -1
- package/src/migrations/latest/terraform-rdb-proxy-iam-connect-grant/migration.js.map +0 -1
- /package/src/migrations/latest/{add-destroy-sandbox-target → react-website-unique-dev-ports}/migration.d.ts +0 -0
- /package/src/migrations/{latest/add-destroy-sandbox-target → v1.0.0-rc.87/0001-add-destroy-sandbox-target}/metadata.json +0 -0
- /package/src/migrations/{latest/python-version-drop-exact-patch → v1.0.0-rc.87/0001-add-destroy-sandbox-target}/migration.d.ts +0 -0
- /package/src/migrations/{latest/add-destroy-sandbox-target → v1.0.0-rc.87/0001-add-destroy-sandbox-target}/migration.js +0 -0
- /package/src/migrations/{latest/terraform-rdb-proxy-iam-connect-grant → v1.0.0-rc.87/0002-terraform-rdb-proxy-iam-connect-grant}/__snapshots__/migration.spec.ts.snap +0 -0
- /package/src/migrations/{latest/terraform-rdb-proxy-iam-connect-grant → v1.0.0-rc.87/0002-terraform-rdb-proxy-iam-connect-grant}/metadata.json +0 -0
- /package/src/migrations/{latest/terraform-rdb-proxy-iam-connect-grant → v1.0.0-rc.87/0002-terraform-rdb-proxy-iam-connect-grant}/migration.d.ts +0 -0
- /package/src/migrations/{latest/terraform-rdb-proxy-iam-connect-grant → v1.0.0-rc.87/0002-terraform-rdb-proxy-iam-connect-grant}/migration.js +0 -0
- /package/src/migrations/{latest/python-version-drop-exact-patch → v1.0.0-rc.88/0001-python-version-drop-exact-patch}/metadata.json +0 -0
- /package/src/migrations/{latest/python-version-drop-exact-patch → v1.0.0-rc.88/0001-python-version-drop-exact-patch}/migration.js +0 -0
- /package/src/migrations/{latest/react-website-nx-react-express-override → v1.0.0-rc.88/0002-react-website-nx-react-express-override}/metadata.json +0 -0
- /package/src/migrations/{latest/react-website-nx-react-express-override → v1.0.0-rc.88/0002-react-website-nx-react-express-override}/migration.d.ts +0 -0
- /package/src/migrations/{latest/react-website-nx-react-express-override → v1.0.0-rc.88/0002-react-website-nx-react-express-override}/migration.js +0 -0
- /package/src/migrations/{latest/nx-parallel-default → v1.0.0-rc.89/0001-nx-parallel-default}/metadata.json +0 -0
- /package/src/migrations/{latest/nx-parallel-default → v1.0.0-rc.89/0001-nx-parallel-default}/migration.d.ts +0 -0
- /package/src/migrations/{latest/nx-parallel-default → v1.0.0-rc.89/0001-nx-parallel-default}/migration.js +0 -0
- /package/src/ts/mcp-server/files/{http.ts.template → app/http.ts.template} +0 -0
- /package/src/ts/mcp-server/files/{index.ts.template → app/index.ts.template} +0 -0
- /package/src/ts/mcp-server/files/{resources → app/resources}/sample-guidance.ts.template +0 -0
- /package/src/ts/mcp-server/files/{server.ts.template → app/server.ts.template} +0 -0
- /package/src/ts/mcp-server/files/{stdio.ts.template → app/stdio.ts.template} +0 -0
- /package/src/ts/mcp-server/files/{tools → app/tools}/divide.ts.template +0 -0
- /package/src/ts/mcp-server/files/{Dockerfile.template → deploy/Dockerfile.template} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/py/agent/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n type GeneratorCallback,\n generateFiles,\n joinPathFragments,\n OverwriteStrategy,\n type Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport { ensureLicenseExceptions } from '../../license/config.js';\nimport { AG_UI_LANGGRAPH_EXCEPTIONS } from '../../license/known-exceptions.js';\nimport {\n addPyDependencies,\n addTsDependencies,\n} from '../../utils/add-dependencies.js';\nimport { addAgentChatScripts } from '../../utils/agent-chat/agent-chat.js';\nimport {\n AGENT_CONNECTION_PY_DEPENDENCIES,\n addPythonFrameworkBase,\n ensureLangchainS3CheckpointSaver,\n ensurePythonAgentConnectionProject,\n getPythonAgentConnectionModuleName,\n getPythonAgentConnectionProject,\n} from '../../utils/agent-connection/agent-connection.js';\nimport { addAgentInfra } from '../../utils/agent-core-constructs/agent-core-constructs.js';\nimport { addPythonBundleTarget } from '../../utils/bundle/bundle.js';\nimport { resolveContainers } from '../../utils/containers.js';\nimport {\n declareDependencies,\n ownedElsewhere,\n} from '../../utils/declared-dependencies.js';\nimport {\n addDockerScanTarget,\n DOCKER_DEPENDENCIES,\n IMAGE_BUILD_CACHE,\n} from '../../utils/docker.js';\nimport { formatFilesInSubtree } from '../../utils/format.js';\nimport { FS_DEPENDENCIES, FsCommands } from '../../utils/fs.js';\nimport { updateGitIgnore } from '../../utils/git.js';\nimport { resolveIac } from '../../utils/iac.js';\nimport { installDependencies } from '../../utils/install.js';\nimport { addGeneratorMetricsIfApplicable } from '../../utils/metrics.js';\nimport { kebabCase, toClassName, toSnakeCase } from '../../utils/names.js';\nimport { getNpmScope } from '../../utils/npm-scope.js';\nimport {\n addArtifactDependencyToTargets,\n addComponentDevTarget,\n addComponentGeneratorMetadata,\n addDependencyToTargetIfNotPresent,\n getGeneratorInfo,\n type NxGeneratorInfo,\n normalizeTargetKeyOrder,\n readProjectConfigurationUnqualified,\n} from '../../utils/nx.js';\nimport { sortObjectKeys } from '../../utils/object.js';\nimport { openApiCodegenTarget } from '../../utils/open-api-codegen-target.js';\nimport {\n getRelativePathToRootByDirectory,\n toProjectRelativePath,\n} from '../../utils/paths.js';\nimport { assignPort } from '../../utils/port.js';\nimport { addWorkspaceDependencyToPyProject } from '../../utils/py.js';\nimport {\n SHARED_CONSTRUCTS_DEPENDENCIES,\n sharedConstructsGenerator,\n} from '../../utils/shared-constructs.js';\nimport type { IacMetadata } from '../../utils/shared-constructs-constants.js';\nimport { BASE_IMAGES } from '../../utils/versions.js';\nimport type {\n AgentProtocol,\n PyAgentFramework,\n PyAgentGeneratorSchema,\n PyAgentSession,\n} from './schema';\n\n/** The metadata this generator records, which its predicates read. */\nexport interface PyAgentMetadata extends IacMetadata {\n readonly port: number;\n readonly rc: string;\n readonly auth: string;\n readonly protocol: AgentProtocol;\n /**\n * The mcp / gateway connection generators dispatch on this field to pick the\n * Strands vs LangChain Layer-2 client + agent.py transform.\n */\n readonly framework: PyAgentFramework;\n readonly session: PyAgentSession;\n}\n\n/** Whether the chat CLI signs its requests, which only IAM auth needs. */\nconst isIam = (m: PyAgentMetadata) => m.auth === 'iam';\n\n// Each entry names the framework and protocol branch it belongs to, so the same\n// declaration drives both adding and the version sync.\nexport const DEPENDENCIES = declareDependencies<PyAgentMetadata>()({\n ts: [\n // The chat CLI, which runs standalone via tsx for every protocol and\n // resolves the deployed agent from AppConfig. `agent-chat-cli` transitively\n // bundles the protocol clients (@a2a-js/sdk, @ag-ui/client).\n { name: 'agent-chat-cli', dev: true, root: true },\n { name: 'tsx', dev: true, root: true },\n { name: '@types/node', dev: true, root: true },\n { name: '@aws-lambda-powertools/parameters', dev: true, root: true },\n { name: '@aws-sdk/client-appconfigdata', dev: true, root: true },\n { name: 'aws4fetch', when: isIam, dev: true, root: true },\n {\n name: '@aws-sdk/credential-providers',\n when: isIam,\n dev: true,\n root: true,\n },\n {\n name: '@a2a-js/sdk',\n when: (m) => m.protocol === 'a2a',\n dev: true,\n root: true,\n },\n // Added by the helpers that own the projects they belong to.\n ...ownedElsewhere(FS_DEPENDENCIES),\n ...ownedElsewhere(DOCKER_DEPENDENCIES),\n ...ownedElsewhere(SHARED_CONSTRUCTS_DEPENDENCIES),\n ],\n py: [\n { name: 'aws-lambda-powertools' },\n { name: 'aws-opentelemetry-distro' },\n { name: 'bedrock-agentcore' },\n { name: 'boto3' },\n { name: 'fastapi' },\n { name: 'mcp' },\n // langchain pulls no Strands dependencies — the langchain model binding\n // plus the per-protocol server adapter: ag-ui-langgraph for AG-UI, a2a-sdk\n // for A2A, nothing extra for HTTP (FastAPI is added for every agent).\n { name: 'langchain', when: (m) => m.framework === 'langchain' },\n { name: 'langchain-aws', when: (m) => m.framework === 'langchain' },\n { name: 'langgraph', when: (m) => m.framework === 'langchain' },\n // Local dev uses a SQLite-backed checkpointer for convenience (parity\n // with the strands framework's local FileSessionManager).\n {\n name: 'langgraph-checkpoint-sqlite',\n when: (m) => m.framework === 'langchain',\n },\n // AsyncSqliteSaver's driver, required alongside langgraph-checkpoint-sqlite.\n { name: 'aiosqlite', when: (m) => m.framework === 'langchain' },\n // Provides DynamoDBSaver (with S3 offloading for large checkpoints).\n {\n name: 'langgraph-checkpoint-aws',\n when: (m) => m.framework === 'langchain' && m.session === 'dynamodb-s3',\n },\n {\n name: 'ag-ui-protocol',\n when: (m) => m.framework === 'langchain' && m.protocol === 'ag-ui',\n },\n {\n name: 'ag-ui-langgraph',\n when: (m) => m.framework === 'langchain' && m.protocol === 'ag-ui',\n },\n {\n name: 'a2a-sdk',\n when: (m) => m.framework === 'langchain' && m.protocol === 'a2a',\n },\n {\n name: 'strands-agents[a2a]',\n when: (m) => m.framework === 'strands' && m.protocol === 'a2a',\n },\n {\n name: 'strands-agents',\n when: (m) => m.framework === 'strands' && m.protocol !== 'a2a',\n },\n {\n name: 'strands-agents-tools',\n when: (m) => m.framework === 'strands',\n },\n // Declared again here so a Strands AG-UI agent lists it in the same order\n // the generated pyproject.toml had before.\n {\n name: 'ag-ui-protocol',\n when: (m) => m.framework === 'strands' && m.protocol === 'ag-ui',\n },\n {\n name: 'ag-ui-strands',\n when: (m) => m.framework === 'strands' && m.protocol === 'ag-ui',\n },\n { name: 'uvicorn' },\n // `fastapi dev` runs the local server for every protocol.\n { name: 'fastapi[standard]', group: 'dev' },\n // The agent-connection helper adds these to its own project.\n ...ownedElsewhere(AGENT_CONNECTION_PY_DEPENDENCIES),\n ],\n});\n\nexport const PY_AGENT_GENERATOR_INFO: NxGeneratorInfo = getGeneratorInfo(\n import.meta.filename,\n);\n\nexport const pyAgentGenerator = async (\n tree: Tree,\n options: PyAgentGeneratorSchema,\n): Promise<GeneratorCallback> => {\n const project = readProjectConfigurationUnqualified(tree, options.project);\n\n const pyProjectPath = joinPathFragments(project.root, 'pyproject.toml');\n\n // Check if the project has a pyproject.toml file\n if (!pyProjectPath) {\n throw new Error(\n `Unsupported project ${options.project}. Expected a Python project (with a pyproject.toml)`,\n );\n }\n\n if (!project.sourceRoot) {\n throw new Error(\n `This project does not have a source root. Please add a source root to the project configuration before running this generator.`,\n );\n }\n\n // Module name is the last part of the source root,\n const sourceParts = project.sourceRoot.split('/');\n const moduleName = sourceParts[sourceParts.length - 1];\n\n const name = kebabCase(\n options.name || `${kebabCase(project.name.split('.').pop())}-agent`,\n );\n const agentTargetPrefix = options.name ? name : 'agent';\n\n const agentNameSnakeCase = toSnakeCase(options.name || 'agent');\n const agentNameClassName = toClassName(name);\n\n const targetSourceDir = joinPathFragments(\n project.sourceRoot,\n agentNameSnakeCase,\n );\n\n const infra = options.infra ?? 'agentcore';\n const protocol = options.protocol ?? 'http';\n const framework = options.framework ?? 'strands';\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 if (infra === 'none' && options.auth && options.auth !== 'iam') {\n console.warn(\n 'Warning: auth is ignored when no infrastructure is configured (no infrastructure is generated)',\n );\n }\n\n const auth = options.auth ?? 'iam';\n\n // Session backends are framework-specific: Strands' SessionManager only has\n // an S3-backed implementation here (via strands.session.S3SessionManager),\n // while LangChain uses dedicated S3 and DynamoDB checkpointer libraries.\n // 'in-memory' is valid for both.\n const SESSIONS_BY_FRAMEWORK: Record<\n PyAgentFramework,\n readonly PyAgentSession[]\n > = {\n strands: ['s3', 'in-memory'],\n langchain: ['s3', 'dynamodb-s3', 'in-memory'],\n };\n if (\n options.session &&\n !SESSIONS_BY_FRAMEWORK[framework].includes(options.session)\n ) {\n throw new Error(\n `Unsupported combination: session '${options.session}' is not implemented for the ${framework} framework (supported: ${SESSIONS_BY_FRAMEWORK[framework].join(', ')}).`,\n );\n }\n const session = options.session ?? 's3';\n\n // With infra=none there's no CDK/Terraform construct to provision a bucket\n // or table or set RUNTIME_CONFIG_APP_ID, so session.py's non-local-dev\n // branch has nothing to read from AppConfig at runtime — the generated code\n // still honors `session`, but only works outside local dev if the caller\n // wires up matching infra/runtime config themselves.\n if (infra === 'none' && session !== 'in-memory') {\n console.warn(\n `Warning: session '${session}' requires infrastructure to configure it automatically (no infrastructure is generated for infra=none) — outside local dev this will fail unless you configure matching runtime config yourself`,\n );\n }\n\n // Local-dev session storage lives at the workspace root\n // (`tmp/agents/<framework>/<agent-name>`), not inside the project, so each\n // agent gets its own storage directory — shared by both frameworks\n // (Strands' FileSessionManager, LangChain's SqliteSaver). The\n // `-dev`/`-serve` targets run with cwd={projectRoot}, so compute that\n // directory relative to the project root here rather than resolving it at\n // runtime.\n const localSessionsDir = joinPathFragments(\n getRelativePathToRootByDirectory(project.root),\n `tmp/agents/${framework}/${name}`,\n );\n\n // Ensure the shared agent-connection project exists so the server entry\n // point can import `session_id_context` and propagate the AgentCore\n // session ID to any downstream MCP / A2A clients a later connection\n // generator wires into this agent.\n await ensurePythonAgentConnectionProject(tree, DEPENDENCIES);\n // The agent server imports the framework base helpers (session cache + model\n // error logging) regardless of whether a connection client is wired in. The\n // LangChain framework has no base layer (its AG-UI foundation reuses only the\n // framework-agnostic session context), so this is a no-op for LangChain.\n await addPythonFrameworkBase(tree, DEPENDENCIES, framework);\n const agentConnectionModuleName = getPythonAgentConnectionModuleName(tree);\n addWorkspaceDependencyToPyProject(\n tree,\n project,\n getPythonAgentConnectionProject(tree),\n );\n\n const templateContext = {\n name,\n agentNameSnakeCase,\n agentNameClassName,\n moduleName,\n agentConnectionModuleName,\n framework,\n protocol,\n session,\n localSessionsDir,\n };\n\n // Files live under a per-framework dir (files/strands, files/langchain),\n // mirrored one-for-one — including files that don't vary by framework\n // (e.g. the empty package __init__.py) — so there's a single, uniform\n // <framework>/<protocol> layout with no cross-framework fallbacks.\n // `framework` is itself the directory name.\n\n // Common files shared by both protocols: the agent module (Strands yields a\n // contextmanaged Agent with a session.py sibling; LangChain returns a\n // compiled create_agent graph) and the package __init__.py.\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', framework, 'common'),\n targetSourceDir,\n templateContext,\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n\n if (framework === 'langchain' && session === 's3') {\n ensureLangchainS3CheckpointSaver(tree);\n }\n\n // Protocol-specific files. Each protocol's server entry point is\n // framework-specific (Strands yields a contextmanaged Agent; LangChain\n // drives a compiled create_agent graph).\n const protocolLower = protocol.toLowerCase();\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', framework, protocolLower),\n targetSourceDir,\n templateContext,\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n\n if (infra === 'agentcore') {\n const containers = await resolveContainers(tree, 'inherit');\n const dockerImageTag = `${getNpmScope(tree)}-${name}:latest`;\n\n // Add bundle target\n const { bundleTargetName, bundleOutputDir } = addPythonBundleTarget(\n project,\n {\n pythonPlatform: 'aarch64-manylinux_2_28',\n },\n );\n\n // Add the Dockerfile\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'deploy'),\n targetSourceDir,\n {\n agentNameSnakeCase,\n moduleName,\n bundleOutputDir,\n protocol,\n pythonBaseImage: BASE_IMAGES.python,\n },\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n\n const dockerOutputDir = joinPathFragments(\n 'dist',\n project.root,\n 'docker',\n name,\n );\n const dockerTargetName = `${agentTargetPrefix}-docker`;\n\n // Add a docker target that prepares the docker context and builds the image\n const fs = new FsCommands(tree, DEPENDENCIES);\n project.targets[dockerTargetName] = {\n cache: IMAGE_BUILD_CACHE,\n executor: 'nx:run-commands',\n options: {\n commands: [\n fs.rm(dockerOutputDir),\n fs.mkdir(dockerOutputDir),\n fs.cp(bundleOutputDir, dockerOutputDir),\n fs.cp(\n `${targetSourceDir}/Dockerfile`,\n `${dockerOutputDir}/Dockerfile`,\n ),\n `${containers} build --platform linux/arm64 -t ${dockerImageTag} ${dockerOutputDir}`,\n ],\n parallel: false,\n },\n dependsOn: [bundleTargetName],\n };\n\n addDependencyToTargetIfNotPresent(project, 'docker', dockerTargetName);\n addArtifactDependencyToTargets(project, 'docker');\n\n addDockerScanTarget(\n tree,\n {\n project,\n containerEngine: containers,\n trivyTargetName: `${agentTargetPrefix}-trivy`,\n dockerTargetName,\n imageTags: [dockerImageTag],\n },\n DEPENDENCIES,\n );\n\n // Add shared constructs\n await sharedConstructsGenerator(tree, { iac }, DEPENDENCIES);\n\n // Add the construct to deploy the agent.\n // AG-UI uses HTTP as the AgentCore protocol type (AG-UI is HTTP-based with SSE over POST).\n const infraProtocol =\n protocol === 'ag-ui' ? ('http' as const) : (protocol as 'http' | 'a2a');\n await addAgentInfra(tree, {\n agentNameKebabCase: name,\n agentNameClassName,\n dockerImageTag,\n dockerOutputDir,\n iac,\n projectName: project.name,\n auth,\n session,\n serverProtocol: infraProtocol,\n containers,\n });\n }\n\n // A2A servers use port 9000 as per the Strands A2A SDK default and AgentCore A2A contract.\n // HTTP and AG-UI agents use port 8081+ to avoid conflict with VS Code server on 8080.\n const localDevPortStart = protocol === 'a2a' ? 9000 : 8081;\n const localDevPort = assignPort(tree, project, localDevPortStart, {\n component: { info: PY_AGENT_GENERATOR_INFO, name: agentTargetPrefix },\n });\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: PyAgentMetadata = {\n port: localDevPort,\n rc: agentNameClassName,\n auth,\n protocol,\n framework,\n session,\n ...(iac ? { iac } : {}),\n };\n\n addPyDependencies(tree, DEPENDENCIES, {\n metadata,\n projectRoot: project.root,\n });\n addTsDependencies(tree, DEPENDENCIES, { metadata });\n\n // All protocols use fastapi dev for hot reload:\n // - HTTP: FastAPI app directly defined in init.py\n // - A2A: A2AServer.to_fastapi_app() creates a FastAPI app in main.py\n // - AG-UI: create_strands_app() creates a FastAPI app in main.py\n const serveCommand = `uv run fastapi dev ${moduleName}/${agentNameSnakeCase}/main.py --port ${localDevPort}`;\n\n // HTTP chat uses the type-safe TypeScript client generated from the\n // agent's OpenAPI spec (same generated client the react-connection\n // generator produces). A2A and AG-UI speak standard protocols, so\n // we can run `agent-chat-cli` directly as a binary.\n const openApiTargetName = `${agentTargetPrefix}-openapi`;\n const clientGenTargetName = `${agentTargetPrefix}-generate-client`;\n\n const scriptsDir = joinPathFragments(\n project.root,\n 'scripts',\n agentTargetPrefix,\n );\n\n if (protocol === 'http') {\n // Emit the OpenAPI spec generator script (shared with react-connection)\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'react-connection',\n 'files',\n 'agent',\n ),\n project.root,\n {\n moduleName,\n agentNameSnakeCase,\n },\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n\n // Ignore the generated client directory\n updateGitIgnore(tree, project.root, (patterns) => [\n ...patterns,\n `scripts/${agentTargetPrefix}/generated/`,\n ]);\n }\n\n // Every protocol gets a standalone `chat.ts`. It connects to the local\n // `dev` server by default, or to the deployed agent (with the\n // appropriate auth) when `RUNTIME_CONFIG_APP_ID` is set.\n addAgentChatScripts(tree, {\n scriptsDir,\n protocol,\n language: 'py',\n agentNameClassName,\n auth,\n });\n\n const chatUrl =\n protocol === 'ag-ui'\n ? `http://localhost:${localDevPort}/invocations`\n : `http://localhost:${localDevPort}`;\n const chatCommand = `tsx ./scripts/${agentTargetPrefix}/chat.ts`;\n\n const httpOnlyTargets =\n protocol === 'http'\n ? {\n [openApiTargetName]: {\n cache: true,\n // The spec serialises models a dependency may own, and this target\n // has no `dependsOn` for `default`'s transitive\n // `dependentTasksOutputFiles` to resolve against — so `^production`\n // is the only edge to the dependency, and without it a model change\n // there serves a stale spec.\n inputs: ['production', '^production'],\n executor: 'nx:run-commands',\n outputs: [\n `{workspaceRoot}/dist/{projectRoot}/openapi/${agentNameSnakeCase}`,\n ],\n options: {\n commands: [\n `uv run python {projectRoot}/scripts/${agentNameSnakeCase}_openapi.py \"dist/{projectRoot}/openapi/${agentNameSnakeCase}/openapi.json\"`,\n ],\n },\n },\n [clientGenTargetName]: openApiCodegenTarget({\n generator: 'ts-client',\n openApiSpecPath: `dist/${project.root}/openapi/${agentNameSnakeCase}/openapi.json`,\n outputPath: `${project.root}/scripts/${agentTargetPrefix}/generated`,\n specBuildTargetName: openApiTargetName,\n outputs: [`{projectRoot}/scripts/${agentTargetPrefix}/generated`],\n }),\n }\n : {};\n\n const agentTargets = {\n ...project.targets,\n ...httpOnlyTargets,\n [`${agentTargetPrefix}-serve`]: {\n executor: 'nx:run-commands',\n continuous: true,\n options: {\n commands: [serveCommand],\n cwd: '{projectRoot}',\n env: {\n PORT: `${localDevPort}`,\n },\n },\n },\n [`${agentTargetPrefix}-dev`]: {\n executor: 'nx:run-commands',\n continuous: true,\n options: {\n commands: [serveCommand],\n cwd: '{projectRoot}',\n env: {\n PORT: `${localDevPort}`,\n LOCAL_DEV: 'true',\n },\n },\n },\n // HTTP chat imports the generated client, so ensure it's built first.\n // No dev dependency — chat runs standalone against a local or\n // deployed agent. normalizeTargetKeyOrder keeps the conditional dependsOn\n // in Nx 23's serialization order so re-runs stay byte-identical.\n [`${agentTargetPrefix}-chat`]: normalizeTargetKeyOrder({\n executor: 'nx:run-commands',\n options: {\n commands: [chatCommand],\n cwd: '{projectRoot}',\n env: {\n URL: chatUrl,\n },\n },\n ...(protocol === 'http' ? { dependsOn: [clientGenTargetName] } : {}),\n }),\n };\n\n // Aggregate `<agent>-dev` under the project-level `dev` target.\n addComponentDevTarget(agentTargets, `${agentTargetPrefix}-dev`);\n\n updateProjectConfiguration(tree, project.name, {\n ...project,\n targets: sortObjectKeys(agentTargets),\n });\n\n addComponentGeneratorMetadata(\n tree,\n project.name,\n PY_AGENT_GENERATOR_INFO,\n toProjectRelativePath(project, targetSourceDir),\n agentTargetPrefix,\n metadata,\n );\n\n await addGeneratorMetricsIfApplicable(tree, [PY_AGENT_GENERATOR_INFO]);\n\n // langchain-core (pulled by every langchain agent regardless of protocol)\n // brings jsonpatch/jsonpointer, whose wheels ship without resolvable SPDX\n // license metadata, so register those exceptions so the workspace license\n // check still passes.\n if (framework === 'langchain') {\n await ensureLicenseExceptions(tree, AG_UI_LANGGRAPH_EXCEPTIONS);\n }\n\n await formatFilesInSubtree(tree);\n return () =>\n installDependencies(tree, options.preferInstallDependencies, {\n languages: ['typescript', 'python'],\n });\n};\n\nexport default pyAgentGenerator;\n"],"names":["generateFiles","joinPathFragments","OverwriteStrategy","updateProjectConfiguration","ensureLicenseExceptions","AG_UI_LANGGRAPH_EXCEPTIONS","addPyDependencies","addTsDependencies","addAgentChatScripts","AGENT_CONNECTION_PY_DEPENDENCIES","addPythonFrameworkBase","ensureLangchainS3CheckpointSaver","ensurePythonAgentConnectionProject","getPythonAgentConnectionModuleName","getPythonAgentConnectionProject","addAgentInfra","addPythonBundleTarget","resolveContainers","declareDependencies","ownedElsewhere","addDockerScanTarget","DOCKER_DEPENDENCIES","IMAGE_BUILD_CACHE","formatFilesInSubtree","FS_DEPENDENCIES","FsCommands","updateGitIgnore","resolveIac","installDependencies","addGeneratorMetricsIfApplicable","kebabCase","toClassName","toSnakeCase","getNpmScope","addArtifactDependencyToTargets","addComponentDevTarget","addComponentGeneratorMetadata","addDependencyToTargetIfNotPresent","getGeneratorInfo","normalizeTargetKeyOrder","readProjectConfigurationUnqualified","sortObjectKeys","openApiCodegenTarget","getRelativePathToRootByDirectory","toProjectRelativePath","assignPort","addWorkspaceDependencyToPyProject","SHARED_CONSTRUCTS_DEPENDENCIES","sharedConstructsGenerator","BASE_IMAGES","isIam","m","auth","DEPENDENCIES","ts","name","dev","root","when","protocol","py","framework","session","group","PY_AGENT_GENERATOR_INFO","filename","pyAgentGenerator","tree","options","project","pyProjectPath","Error","sourceRoot","sourceParts","split","moduleName","length","pop","agentTargetPrefix","agentNameSnakeCase","agentNameClassName","targetSourceDir","infra","iac","undefined","console","warn","SESSIONS_BY_FRAMEWORK","strands","langchain","includes","join","localSessionsDir","agentConnectionModuleName","templateContext","dirname","overwriteStrategy","KeepExisting","protocolLower","toLowerCase","containers","dockerImageTag","bundleTargetName","bundleOutputDir","pythonPlatform","pythonBaseImage","python","dockerOutputDir","dockerTargetName","fs","targets","cache","executor","commands","rm","mkdir","cp","parallel","dependsOn","containerEngine","trivyTargetName","imageTags","infraProtocol","agentNameKebabCase","projectName","serverProtocol","localDevPortStart","localDevPort","component","info","metadata","port","rc","projectRoot","serveCommand","openApiTargetName","clientGenTargetName","scriptsDir","patterns","language","chatUrl","chatCommand","httpOnlyTargets","inputs","outputs","generator","openApiSpecPath","outputPath","specBuildTargetName","agentTargets","continuous","cwd","env","PORT","LOCAL_DEV","URL","preferInstallDependencies","languages"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/py/agent/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n type GeneratorCallback,\n generateFiles,\n joinPathFragments,\n OverwriteStrategy,\n type Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport { ensureLicenseExceptions } from '../../license/config.js';\nimport { AG_UI_LANGGRAPH_EXCEPTIONS } from '../../license/known-exceptions.js';\nimport {\n addPyDependencies,\n addTsDependencies,\n} from '../../utils/add-dependencies.js';\nimport { addAgentChatScripts } from '../../utils/agent-chat/agent-chat.js';\nimport {\n AGENT_CONNECTION_PY_DEPENDENCIES,\n addPythonFrameworkBase,\n ensureLangchainS3CheckpointSaver,\n ensurePythonAgentConnectionProject,\n getPythonAgentConnectionModuleName,\n getPythonAgentConnectionProject,\n} from '../../utils/agent-connection/agent-connection.js';\nimport {\n type AgentCoreArtifact,\n addAgentInfra,\n} from '../../utils/agent-core-constructs/agent-core-constructs.js';\nimport {\n addPythonCodePackageTarget,\n agentCorePythonRuntime,\n isAgentCoreHosted,\n isContainerHosted,\n} from '../../utils/agent-core-packaging.js';\nimport { addPythonBundleTarget } from '../../utils/bundle/bundle.js';\nimport { resolveContainers } from '../../utils/containers.js';\nimport {\n declareDependencies,\n ownedElsewhere,\n} from '../../utils/declared-dependencies.js';\nimport {\n addDockerScanTarget,\n DOCKER_DEPENDENCIES,\n IMAGE_BUILD_CACHE,\n} from '../../utils/docker.js';\nimport { formatFilesInSubtree } from '../../utils/format.js';\nimport { FS_DEPENDENCIES, FsCommands } from '../../utils/fs.js';\nimport { updateGitIgnore } from '../../utils/git.js';\nimport { resolveIac } from '../../utils/iac.js';\nimport { installDependencies } from '../../utils/install.js';\nimport { addGeneratorMetricsIfApplicable } from '../../utils/metrics.js';\nimport { kebabCase, toClassName, toSnakeCase } from '../../utils/names.js';\nimport { getNpmScope } from '../../utils/npm-scope.js';\nimport {\n addArtifactDependencyToTargets,\n addComponentDevTarget,\n addComponentGeneratorMetadata,\n addDependencyToTargetIfNotPresent,\n getGeneratorInfo,\n type NxGeneratorInfo,\n normalizeTargetKeyOrder,\n readProjectConfigurationUnqualified,\n} from '../../utils/nx.js';\nimport { sortObjectKeys } from '../../utils/object.js';\nimport { openApiCodegenTarget } from '../../utils/open-api-codegen-target.js';\nimport {\n getRelativePathToRootByDirectory,\n toProjectRelativePath,\n} from '../../utils/paths.js';\nimport { assignPort } from '../../utils/port.js';\nimport { addWorkspaceDependencyToPyProject } from '../../utils/py.js';\nimport {\n SHARED_CONSTRUCTS_DEPENDENCIES,\n sharedConstructsGenerator,\n} from '../../utils/shared-constructs.js';\nimport type { IacMetadata } from '../../utils/shared-constructs-constants.js';\nimport { BASE_IMAGES } from '../../utils/versions.js';\nimport type {\n AgentProtocol,\n PyAgentFramework,\n PyAgentGeneratorSchema,\n PyAgentInfra,\n PyAgentSession,\n} from './schema';\n\n/** The metadata this generator records, which its predicates read. */\nexport interface PyAgentMetadata extends IacMetadata {\n readonly port: number;\n readonly rc: string;\n readonly auth: string;\n readonly protocol: AgentProtocol;\n /**\n * The mcp / gateway connection generators dispatch on this field to pick the\n * Strands vs LangChain Layer-2 client + agent.py transform.\n */\n readonly framework: PyAgentFramework;\n readonly session: PyAgentSession;\n /**\n * How this component is packaged and hosted, so a consumer can tell a\n * code-packaged runtime from a container-packaged one without re-deriving it.\n */\n readonly infra: PyAgentInfra;\n}\n\n/** Whether the chat CLI signs its requests, which only IAM auth needs. */\nconst isIam = (m: PyAgentMetadata) => m.auth === 'iam';\n\n// Each entry names the framework and protocol branch it belongs to, so the same\n// declaration drives both adding and the version sync.\nexport const DEPENDENCIES = declareDependencies<PyAgentMetadata>()({\n ts: [\n // The chat CLI, which runs standalone via tsx for every protocol and\n // resolves the deployed agent from AppConfig. `agent-chat-cli` transitively\n // bundles the protocol clients (@a2a-js/sdk, @ag-ui/client).\n { name: 'agent-chat-cli', dev: true, root: true },\n { name: 'tsx', dev: true, root: true },\n { name: '@types/node', dev: true, root: true },\n { name: '@aws-lambda-powertools/parameters', dev: true, root: true },\n { name: '@aws-sdk/client-appconfigdata', dev: true, root: true },\n { name: 'aws4fetch', when: isIam, dev: true, root: true },\n {\n name: '@aws-sdk/credential-providers',\n when: isIam,\n dev: true,\n root: true,\n },\n {\n name: '@a2a-js/sdk',\n when: (m) => m.protocol === 'a2a',\n dev: true,\n root: true,\n },\n // Added by the helpers that own the projects they belong to.\n ...ownedElsewhere(FS_DEPENDENCIES),\n ...ownedElsewhere(DOCKER_DEPENDENCIES),\n ...ownedElsewhere(SHARED_CONSTRUCTS_DEPENDENCIES),\n ],\n py: [\n { name: 'aws-lambda-powertools' },\n { name: 'aws-opentelemetry-distro' },\n { name: 'bedrock-agentcore' },\n { name: 'boto3' },\n { name: 'fastapi' },\n { name: 'mcp' },\n // langchain pulls no Strands dependencies — the langchain model binding\n // plus the per-protocol server adapter: ag-ui-langgraph for AG-UI, a2a-sdk\n // for A2A, nothing extra for HTTP (FastAPI is added for every agent).\n { name: 'langchain', when: (m) => m.framework === 'langchain' },\n { name: 'langchain-aws', when: (m) => m.framework === 'langchain' },\n { name: 'langgraph', when: (m) => m.framework === 'langchain' },\n // Local dev uses a SQLite-backed checkpointer for convenience (parity\n // with the strands framework's local FileSessionManager).\n {\n name: 'langgraph-checkpoint-sqlite',\n when: (m) => m.framework === 'langchain',\n },\n // AsyncSqliteSaver's driver, required alongside langgraph-checkpoint-sqlite.\n { name: 'aiosqlite', when: (m) => m.framework === 'langchain' },\n // Provides DynamoDBSaver (with S3 offloading for large checkpoints).\n {\n name: 'langgraph-checkpoint-aws',\n when: (m) => m.framework === 'langchain' && m.session === 'dynamodb-s3',\n },\n {\n name: 'ag-ui-protocol',\n when: (m) => m.framework === 'langchain' && m.protocol === 'ag-ui',\n },\n {\n name: 'ag-ui-langgraph',\n when: (m) => m.framework === 'langchain' && m.protocol === 'ag-ui',\n },\n {\n name: 'a2a-sdk',\n when: (m) => m.framework === 'langchain' && m.protocol === 'a2a',\n },\n {\n name: 'strands-agents[a2a]',\n when: (m) => m.framework === 'strands' && m.protocol === 'a2a',\n },\n {\n name: 'strands-agents',\n when: (m) => m.framework === 'strands' && m.protocol !== 'a2a',\n },\n {\n name: 'strands-agents-tools',\n when: (m) => m.framework === 'strands',\n },\n // Declared again here so a Strands AG-UI agent lists it in the same order\n // the generated pyproject.toml had before.\n {\n name: 'ag-ui-protocol',\n when: (m) => m.framework === 'strands' && m.protocol === 'ag-ui',\n },\n {\n name: 'ag-ui-strands',\n when: (m) => m.framework === 'strands' && m.protocol === 'ag-ui',\n },\n { name: 'uvicorn' },\n // `fastapi dev` runs the local server for every protocol.\n { name: 'fastapi[standard]', group: 'dev' },\n // The agent-connection helper adds these to its own project.\n ...ownedElsewhere(AGENT_CONNECTION_PY_DEPENDENCIES),\n ],\n});\n\nexport const PY_AGENT_GENERATOR_INFO: NxGeneratorInfo = getGeneratorInfo(\n import.meta.filename,\n);\n\nexport const pyAgentGenerator = async (\n tree: Tree,\n options: PyAgentGeneratorSchema,\n): Promise<GeneratorCallback> => {\n const project = readProjectConfigurationUnqualified(tree, options.project);\n\n const pyProjectPath = joinPathFragments(project.root, 'pyproject.toml');\n\n // Check if the project has a pyproject.toml file\n if (!pyProjectPath) {\n throw new Error(\n `Unsupported project ${options.project}. Expected a Python project (with a pyproject.toml)`,\n );\n }\n\n if (!project.sourceRoot) {\n throw new Error(\n `This project does not have a source root. Please add a source root to the project configuration before running this generator.`,\n );\n }\n\n // Module name is the last part of the source root,\n const sourceParts = project.sourceRoot.split('/');\n const moduleName = sourceParts[sourceParts.length - 1];\n\n const name = kebabCase(\n options.name || `${kebabCase(project.name.split('.').pop())}-agent`,\n );\n const agentTargetPrefix = options.name ? name : 'agent';\n\n const agentNameSnakeCase = toSnakeCase(options.name || 'agent');\n const agentNameClassName = toClassName(name);\n\n const targetSourceDir = joinPathFragments(\n project.sourceRoot,\n agentNameSnakeCase,\n );\n\n const infra = options.infra ?? 'agentcore';\n const protocol = options.protocol ?? 'http';\n const framework = options.framework ?? 'strands';\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 if (infra === 'none' && options.auth && options.auth !== 'iam') {\n console.warn(\n 'Warning: auth is ignored when no infrastructure is configured (no infrastructure is generated)',\n );\n }\n\n const auth = options.auth ?? 'iam';\n\n // Session backends are framework-specific: Strands' SessionManager only has\n // an S3-backed implementation here (via strands.session.S3SessionManager),\n // while LangChain uses dedicated S3 and DynamoDB checkpointer libraries.\n // 'in-memory' is valid for both.\n const SESSIONS_BY_FRAMEWORK: Record<\n PyAgentFramework,\n readonly PyAgentSession[]\n > = {\n strands: ['s3', 'in-memory'],\n langchain: ['s3', 'dynamodb-s3', 'in-memory'],\n };\n if (\n options.session &&\n !SESSIONS_BY_FRAMEWORK[framework].includes(options.session)\n ) {\n throw new Error(\n `Unsupported combination: session '${options.session}' is not implemented for the ${framework} framework (supported: ${SESSIONS_BY_FRAMEWORK[framework].join(', ')}).`,\n );\n }\n const session = options.session ?? 's3';\n\n // With infra=none there's no CDK/Terraform construct to provision a bucket\n // or table or set RUNTIME_CONFIG_APP_ID, so session.py's non-local-dev\n // branch has nothing to read from AppConfig at runtime — the generated code\n // still honors `session`, but only works outside local dev if the caller\n // wires up matching infra/runtime config themselves.\n if (infra === 'none' && session !== 'in-memory') {\n console.warn(\n `Warning: session '${session}' requires infrastructure to configure it automatically (no infrastructure is generated for infra=none) — outside local dev this will fail unless you configure matching runtime config yourself`,\n );\n }\n\n // Local-dev session storage lives at the workspace root\n // (`tmp/agents/<framework>/<agent-name>`), not inside the project, so each\n // agent gets its own storage directory — shared by both frameworks\n // (Strands' FileSessionManager, LangChain's SqliteSaver). The\n // `-dev`/`-serve` targets run with cwd={projectRoot}, so compute that\n // directory relative to the project root here rather than resolving it at\n // runtime.\n const localSessionsDir = joinPathFragments(\n getRelativePathToRootByDirectory(project.root),\n `tmp/agents/${framework}/${name}`,\n );\n\n // Ensure the shared agent-connection project exists so the server entry\n // point can import `session_id_context` and propagate the AgentCore\n // session ID to any downstream MCP / A2A clients a later connection\n // generator wires into this agent.\n await ensurePythonAgentConnectionProject(tree, DEPENDENCIES);\n // The agent server imports the framework base helpers (session cache + model\n // error logging) regardless of whether a connection client is wired in. The\n // LangChain framework has no base layer (its AG-UI foundation reuses only the\n // framework-agnostic session context), so this is a no-op for LangChain.\n await addPythonFrameworkBase(tree, DEPENDENCIES, framework);\n const agentConnectionModuleName = getPythonAgentConnectionModuleName(tree);\n addWorkspaceDependencyToPyProject(\n tree,\n project,\n getPythonAgentConnectionProject(tree),\n );\n\n const templateContext = {\n name,\n agentNameSnakeCase,\n agentNameClassName,\n moduleName,\n agentConnectionModuleName,\n framework,\n protocol,\n session,\n localSessionsDir,\n };\n\n // Files live under a per-framework dir (files/strands, files/langchain),\n // mirrored one-for-one — including files that don't vary by framework\n // (e.g. the empty package __init__.py) — so there's a single, uniform\n // <framework>/<protocol> layout with no cross-framework fallbacks.\n // `framework` is itself the directory name.\n\n // Common files shared by both protocols: the agent module (Strands yields a\n // contextmanaged Agent with a session.py sibling; LangChain returns a\n // compiled create_agent graph) and the package __init__.py.\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', framework, 'common'),\n targetSourceDir,\n templateContext,\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n\n if (framework === 'langchain' && session === 's3') {\n ensureLangchainS3CheckpointSaver(tree);\n }\n\n // Protocol-specific files. Each protocol's server entry point is\n // framework-specific (Strands yields a contextmanaged Agent; LangChain\n // drives a compiled create_agent graph).\n const protocolLower = protocol.toLowerCase();\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', framework, protocolLower),\n targetSourceDir,\n templateContext,\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n\n if (isAgentCoreHosted(infra)) {\n const container = isContainerHosted(infra);\n const containers = await resolveContainers(tree, 'inherit');\n const dockerImageTag = `${getNpmScope(tree)}-${name}:latest`;\n\n // Add bundle target\n const { bundleTargetName, bundleOutputDir } = addPythonBundleTarget(\n project,\n {\n pythonPlatform: 'aarch64-manylinux_2_28',\n },\n );\n\n let artifact: AgentCoreArtifact;\n\n if (container) {\n // Add the Dockerfile\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'deploy'),\n targetSourceDir,\n {\n agentNameSnakeCase,\n moduleName,\n bundleOutputDir,\n protocol,\n pythonBaseImage: BASE_IMAGES.python,\n },\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n\n const dockerOutputDir = joinPathFragments(\n 'dist',\n project.root,\n 'docker',\n name,\n );\n const dockerTargetName = `${agentTargetPrefix}-docker`;\n\n // Add a docker target that prepares the docker context and builds the image\n const fs = new FsCommands(tree, DEPENDENCIES);\n project.targets[dockerTargetName] = {\n cache: IMAGE_BUILD_CACHE,\n executor: 'nx:run-commands',\n options: {\n commands: [\n fs.rm(dockerOutputDir),\n fs.mkdir(dockerOutputDir),\n fs.cp(bundleOutputDir, dockerOutputDir),\n fs.cp(\n `${targetSourceDir}/Dockerfile`,\n `${dockerOutputDir}/Dockerfile`,\n ),\n `${containers} build --platform linux/arm64 -t ${dockerImageTag} ${dockerOutputDir}`,\n ],\n parallel: false,\n },\n dependsOn: [bundleTargetName],\n };\n\n addDependencyToTargetIfNotPresent(project, 'docker', dockerTargetName);\n addArtifactDependencyToTargets(project, 'docker');\n\n addDockerScanTarget(\n tree,\n {\n project,\n containerEngine: containers,\n trivyTargetName: `${agentTargetPrefix}-trivy`,\n dockerTargetName,\n imageTags: [dockerImageTag],\n },\n DEPENDENCIES,\n );\n\n artifact = {\n type: 'container',\n dockerImageTag,\n outputDir: dockerOutputDir,\n };\n } else {\n // The entry point the managed runtime runs, at the package root.\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'package'),\n joinPathFragments(project.root, 'package', agentNameSnakeCase),\n {\n agentNameSnakeCase,\n moduleName,\n port: protocol === 'a2a' ? 9000 : 8080,\n },\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n\n const packageOutputDir = joinPathFragments(\n 'dist',\n project.root,\n 'package',\n name,\n );\n addPythonCodePackageTarget(\n tree,\n {\n project,\n targetName: `${agentTargetPrefix}-package`,\n bundleTargetName,\n bundleOutputDir,\n packageOutputDir,\n sourceRoot: project.sourceRoot,\n moduleName,\n entryPointPath: joinPathFragments(\n project.root,\n 'package',\n agentNameSnakeCase,\n 'main.py',\n ),\n entryPointFileName: 'main.py',\n },\n DEPENDENCIES,\n );\n\n artifact = {\n type: 'code',\n outputDir: packageOutputDir,\n runtime: agentCorePythonRuntime(),\n entryPoint: 'main.py',\n };\n }\n\n // Add shared constructs\n await sharedConstructsGenerator(tree, { iac }, DEPENDENCIES);\n\n // Add the construct to deploy the agent.\n // AG-UI uses HTTP as the AgentCore protocol type (AG-UI is HTTP-based with SSE over POST).\n const infraProtocol =\n protocol === 'ag-ui' ? ('http' as const) : (protocol as 'http' | 'a2a');\n await addAgentInfra(tree, {\n agentNameKebabCase: name,\n agentNameClassName,\n artifact,\n iac,\n projectName: project.name,\n auth,\n session,\n serverProtocol: infraProtocol,\n containers,\n });\n }\n\n // A2A servers use port 9000 as per the Strands A2A SDK default and AgentCore A2A contract.\n // HTTP and AG-UI agents use port 8081+ to avoid conflict with VS Code server on 8080.\n const localDevPortStart = protocol === 'a2a' ? 9000 : 8081;\n const localDevPort = assignPort(tree, project, localDevPortStart, {\n component: { info: PY_AGENT_GENERATOR_INFO, name: agentTargetPrefix },\n });\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: PyAgentMetadata = {\n infra,\n port: localDevPort,\n rc: agentNameClassName,\n auth,\n protocol,\n framework,\n session,\n ...(iac ? { iac } : {}),\n };\n\n addPyDependencies(tree, DEPENDENCIES, {\n metadata,\n projectRoot: project.root,\n });\n addTsDependencies(tree, DEPENDENCIES, { metadata });\n\n // All protocols use fastapi dev for hot reload:\n // - HTTP: FastAPI app directly defined in init.py\n // - A2A: A2AServer.to_fastapi_app() creates a FastAPI app in main.py\n // - AG-UI: create_strands_app() creates a FastAPI app in main.py\n const serveCommand = `uv run fastapi dev ${moduleName}/${agentNameSnakeCase}/main.py --port ${localDevPort}`;\n\n // HTTP chat uses the type-safe TypeScript client generated from the\n // agent's OpenAPI spec (same generated client the react-connection\n // generator produces). A2A and AG-UI speak standard protocols, so\n // we can run `agent-chat-cli` directly as a binary.\n const openApiTargetName = `${agentTargetPrefix}-openapi`;\n const clientGenTargetName = `${agentTargetPrefix}-generate-client`;\n\n const scriptsDir = joinPathFragments(\n project.root,\n 'scripts',\n agentTargetPrefix,\n );\n\n if (protocol === 'http') {\n // Emit the OpenAPI spec generator script (shared with react-connection)\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'react-connection',\n 'files',\n 'agent',\n ),\n project.root,\n {\n moduleName,\n agentNameSnakeCase,\n },\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n\n // Ignore the generated client directory\n updateGitIgnore(tree, project.root, (patterns) => [\n ...patterns,\n `scripts/${agentTargetPrefix}/generated/`,\n ]);\n }\n\n // Every protocol gets a standalone `chat.ts`. It connects to the local\n // `dev` server by default, or to the deployed agent (with the\n // appropriate auth) when `RUNTIME_CONFIG_APP_ID` is set.\n addAgentChatScripts(tree, {\n scriptsDir,\n protocol,\n language: 'py',\n agentNameClassName,\n auth,\n });\n\n const chatUrl =\n protocol === 'ag-ui'\n ? `http://localhost:${localDevPort}/invocations`\n : `http://localhost:${localDevPort}`;\n const chatCommand = `tsx ./scripts/${agentTargetPrefix}/chat.ts`;\n\n const httpOnlyTargets =\n protocol === 'http'\n ? {\n [openApiTargetName]: {\n cache: true,\n // The spec serialises models a dependency may own, and this target\n // has no `dependsOn` for `default`'s transitive\n // `dependentTasksOutputFiles` to resolve against — so `^production`\n // is the only edge to the dependency, and without it a model change\n // there serves a stale spec.\n inputs: ['production', '^production'],\n executor: 'nx:run-commands',\n outputs: [\n `{workspaceRoot}/dist/{projectRoot}/openapi/${agentNameSnakeCase}`,\n ],\n options: {\n commands: [\n `uv run python {projectRoot}/scripts/${agentNameSnakeCase}_openapi.py \"dist/{projectRoot}/openapi/${agentNameSnakeCase}/openapi.json\"`,\n ],\n },\n },\n [clientGenTargetName]: openApiCodegenTarget({\n generator: 'ts-client',\n openApiSpecPath: `dist/${project.root}/openapi/${agentNameSnakeCase}/openapi.json`,\n outputPath: `${project.root}/scripts/${agentTargetPrefix}/generated`,\n specBuildTargetName: openApiTargetName,\n outputs: [`{projectRoot}/scripts/${agentTargetPrefix}/generated`],\n }),\n }\n : {};\n\n const agentTargets = {\n ...project.targets,\n ...httpOnlyTargets,\n [`${agentTargetPrefix}-serve`]: {\n executor: 'nx:run-commands',\n continuous: true,\n options: {\n commands: [serveCommand],\n cwd: '{projectRoot}',\n env: {\n PORT: `${localDevPort}`,\n },\n },\n },\n [`${agentTargetPrefix}-dev`]: {\n executor: 'nx:run-commands',\n continuous: true,\n options: {\n commands: [serveCommand],\n cwd: '{projectRoot}',\n env: {\n PORT: `${localDevPort}`,\n LOCAL_DEV: 'true',\n },\n },\n },\n // HTTP chat imports the generated client, so ensure it's built first.\n // No dev dependency — chat runs standalone against a local or\n // deployed agent. normalizeTargetKeyOrder keeps the conditional dependsOn\n // in Nx 23's serialization order so re-runs stay byte-identical.\n [`${agentTargetPrefix}-chat`]: normalizeTargetKeyOrder({\n executor: 'nx:run-commands',\n options: {\n commands: [chatCommand],\n cwd: '{projectRoot}',\n env: {\n URL: chatUrl,\n },\n },\n ...(protocol === 'http' ? { dependsOn: [clientGenTargetName] } : {}),\n }),\n };\n\n // Aggregate `<agent>-dev` under the project-level `dev` target.\n addComponentDevTarget(agentTargets, `${agentTargetPrefix}-dev`);\n\n updateProjectConfiguration(tree, project.name, {\n ...project,\n targets: sortObjectKeys(agentTargets),\n });\n\n addComponentGeneratorMetadata(\n tree,\n project.name,\n PY_AGENT_GENERATOR_INFO,\n toProjectRelativePath(project, targetSourceDir),\n agentTargetPrefix,\n metadata,\n );\n\n await addGeneratorMetricsIfApplicable(tree, [PY_AGENT_GENERATOR_INFO]);\n\n // langchain-core (pulled by every langchain agent regardless of protocol)\n // brings jsonpatch/jsonpointer, whose wheels ship without resolvable SPDX\n // license metadata, so register those exceptions so the workspace license\n // check still passes.\n if (framework === 'langchain') {\n await ensureLicenseExceptions(tree, AG_UI_LANGGRAPH_EXCEPTIONS);\n }\n\n await formatFilesInSubtree(tree);\n return () =>\n installDependencies(tree, options.preferInstallDependencies, {\n languages: ['typescript', 'python'],\n });\n};\n\nexport default pyAgentGenerator;\n"],"names":["generateFiles","joinPathFragments","OverwriteStrategy","updateProjectConfiguration","ensureLicenseExceptions","AG_UI_LANGGRAPH_EXCEPTIONS","addPyDependencies","addTsDependencies","addAgentChatScripts","AGENT_CONNECTION_PY_DEPENDENCIES","addPythonFrameworkBase","ensureLangchainS3CheckpointSaver","ensurePythonAgentConnectionProject","getPythonAgentConnectionModuleName","getPythonAgentConnectionProject","addAgentInfra","addPythonCodePackageTarget","agentCorePythonRuntime","isAgentCoreHosted","isContainerHosted","addPythonBundleTarget","resolveContainers","declareDependencies","ownedElsewhere","addDockerScanTarget","DOCKER_DEPENDENCIES","IMAGE_BUILD_CACHE","formatFilesInSubtree","FS_DEPENDENCIES","FsCommands","updateGitIgnore","resolveIac","installDependencies","addGeneratorMetricsIfApplicable","kebabCase","toClassName","toSnakeCase","getNpmScope","addArtifactDependencyToTargets","addComponentDevTarget","addComponentGeneratorMetadata","addDependencyToTargetIfNotPresent","getGeneratorInfo","normalizeTargetKeyOrder","readProjectConfigurationUnqualified","sortObjectKeys","openApiCodegenTarget","getRelativePathToRootByDirectory","toProjectRelativePath","assignPort","addWorkspaceDependencyToPyProject","SHARED_CONSTRUCTS_DEPENDENCIES","sharedConstructsGenerator","BASE_IMAGES","isIam","m","auth","DEPENDENCIES","ts","name","dev","root","when","protocol","py","framework","session","group","PY_AGENT_GENERATOR_INFO","filename","pyAgentGenerator","tree","options","project","pyProjectPath","Error","sourceRoot","sourceParts","split","moduleName","length","pop","agentTargetPrefix","agentNameSnakeCase","agentNameClassName","targetSourceDir","infra","iac","undefined","console","warn","SESSIONS_BY_FRAMEWORK","strands","langchain","includes","join","localSessionsDir","agentConnectionModuleName","templateContext","dirname","overwriteStrategy","KeepExisting","protocolLower","toLowerCase","container","containers","dockerImageTag","bundleTargetName","bundleOutputDir","pythonPlatform","artifact","pythonBaseImage","python","dockerOutputDir","dockerTargetName","fs","targets","cache","executor","commands","rm","mkdir","cp","parallel","dependsOn","containerEngine","trivyTargetName","imageTags","type","outputDir","port","packageOutputDir","targetName","entryPointPath","entryPointFileName","runtime","entryPoint","infraProtocol","agentNameKebabCase","projectName","serverProtocol","localDevPortStart","localDevPort","component","info","metadata","rc","projectRoot","serveCommand","openApiTargetName","clientGenTargetName","scriptsDir","patterns","language","chatUrl","chatCommand","httpOnlyTargets","inputs","outputs","generator","openApiSpecPath","outputPath","specBuildTargetName","agentTargets","continuous","cwd","env","PORT","LOCAL_DEV","URL","preferInstallDependencies","languages"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/py/agent/schema.d.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { IacOption } from '../../utils/iac.js';\n\nexport type PyAgentFramework = 'strands' | 'langchain';\nexport type PyAgentInfra =
|
|
1
|
+
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/py/agent/schema.d.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { AgentCoreInfra } from '../../utils/agent-core-packaging.js';\nimport { IacOption } from '../../utils/iac.js';\n\nexport type PyAgentFramework = 'strands' | 'langchain';\nexport type PyAgentInfra = AgentCoreInfra;\nexport type AgentProtocol = 'http' | 'a2a' | 'ag-ui';\n\nexport type PyAgentAuth = 'iam' | 'cognito';\n\nexport type PyAgentSession = 's3' | 'dynamodb-s3' | 'in-memory';\n\nexport interface PyAgentGeneratorSchema {\n project: string;\n framework?: PyAgentFramework;\n name?: string;\n infra?: PyAgentInfra;\n auth?: PyAgentAuth;\n protocol?: AgentProtocol;\n session?: PyAgentSession;\n iac: IacOption;\n preferInstallDependencies?: boolean;\n}\n"],"names":[],"mappings":"AAAA;;;CAGC,GAaD,WAUC"}
|
package/src/py/agent/schema.d.ts
CHANGED
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
import { AgentCoreInfra } from '../../utils/agent-core-packaging.js';
|
|
6
7
|
import { IacOption } from '../../utils/iac.js';
|
|
7
8
|
|
|
8
9
|
export type PyAgentFramework = 'strands' | 'langchain';
|
|
9
|
-
export type PyAgentInfra =
|
|
10
|
+
export type PyAgentInfra = AgentCoreInfra;
|
|
10
11
|
export type AgentProtocol = 'http' | 'a2a' | 'ag-ui';
|
|
11
12
|
|
|
12
13
|
export type PyAgentAuth = 'iam' | 'cognito';
|
package/src/py/agent/schema.json
CHANGED
|
@@ -55,9 +55,9 @@
|
|
|
55
55
|
},
|
|
56
56
|
"infra": {
|
|
57
57
|
"type": "string",
|
|
58
|
-
"description": "The type of infrastructure to host your Agent.",
|
|
58
|
+
"description": "The type of infrastructure to host your Agent. agentcore deploys your code as a zip to an AgentCore managed runtime for the fastest build and deploy cycle. agentcore-ecr builds and hosts a container image instead, for OS-level control or an established container pipeline.",
|
|
59
59
|
"x-prompt": "How would you like to host your Agent server?",
|
|
60
|
-
"enum": ["agentcore", "none"],
|
|
60
|
+
"enum": ["agentcore", "agentcore-ecr", "none"],
|
|
61
61
|
"default": "agentcore",
|
|
62
62
|
"x-priority": "important"
|
|
63
63
|
},
|
|
@@ -157,10 +157,6 @@ exports[`py#mcp-server generator > should match snapshot for Terraform generated
|
|
|
157
157
|
source = "hashicorp/aws"
|
|
158
158
|
version = "6.62.0"
|
|
159
159
|
}
|
|
160
|
-
external = {
|
|
161
|
-
source = "hashicorp/external"
|
|
162
|
-
version = "2.4.1"
|
|
163
|
-
}
|
|
164
160
|
null = {
|
|
165
161
|
source = "hashicorp/null"
|
|
166
162
|
version = "3.3.1"
|
|
@@ -204,9 +200,36 @@ variable "authorizer_configuration" {
|
|
|
204
200
|
default = null
|
|
205
201
|
}
|
|
206
202
|
|
|
207
|
-
variable "
|
|
208
|
-
description = "
|
|
209
|
-
type
|
|
203
|
+
variable "container_configuration" {
|
|
204
|
+
description = "Container artifact for this runtime. Set exactly one of this or \`code_configuration\`; the \`agent-core-container\` module renders it."
|
|
205
|
+
type = object({
|
|
206
|
+
container_uri = string
|
|
207
|
+
})
|
|
208
|
+
default = null
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
variable "code_configuration" {
|
|
212
|
+
description = "Code artifact for this runtime. Set exactly one of this or \`container_configuration\`; the \`agent-core-code\` module renders it."
|
|
213
|
+
type = object({
|
|
214
|
+
entry_point = list(string)
|
|
215
|
+
runtime = string
|
|
216
|
+
s3_bucket = string
|
|
217
|
+
s3_key = string
|
|
218
|
+
})
|
|
219
|
+
default = null
|
|
220
|
+
|
|
221
|
+
validation {
|
|
222
|
+
# Evaluated at plan time, since Terraform defers validation that reads
|
|
223
|
+
# another variable.
|
|
224
|
+
condition = (var.code_configuration == null) != (var.container_configuration == null)
|
|
225
|
+
error_message = "Set exactly one of code_configuration or container_configuration."
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
variable "artifact_dependencies" {
|
|
230
|
+
description = "Resources the artifact is produced by (an image push or a code upload), so the runtime is created only once they exist."
|
|
231
|
+
type = list(any)
|
|
232
|
+
default = []
|
|
210
233
|
}
|
|
211
234
|
|
|
212
235
|
variable "env" {
|
|
@@ -269,47 +292,6 @@ resource "random_id" "unique_suffix" {
|
|
|
269
292
|
byte_length = 4
|
|
270
293
|
}
|
|
271
294
|
|
|
272
|
-
# ECR Repository
|
|
273
|
-
resource "aws_ecr_repository" "agent_core_repository" {
|
|
274
|
-
#checkov:skip=CKV_AWS_136:AES256 encryption is sufficient for ECR repositories
|
|
275
|
-
name = "\${lower(var.agent_runtime_name)}_repository_\${random_id.unique_suffix.hex}"
|
|
276
|
-
|
|
277
|
-
image_tag_mutability = "IMMUTABLE"
|
|
278
|
-
force_delete = true
|
|
279
|
-
|
|
280
|
-
image_scanning_configuration {
|
|
281
|
-
scan_on_push = true
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
tags = var.tags
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
# ECR Repository Policy
|
|
288
|
-
resource "aws_ecr_repository_policy" "agent_core_ecr_policy" {
|
|
289
|
-
repository = aws_ecr_repository.agent_core_repository.name
|
|
290
|
-
|
|
291
|
-
policy = jsonencode({
|
|
292
|
-
Version = "2012-10-17"
|
|
293
|
-
Statement = [
|
|
294
|
-
{
|
|
295
|
-
Sid = "AllowPushPull"
|
|
296
|
-
Effect = "Allow"
|
|
297
|
-
Principal = {
|
|
298
|
-
AWS = "arn:aws:iam::\${local.aws_account_id}:root"
|
|
299
|
-
}
|
|
300
|
-
Action = [
|
|
301
|
-
"ecr:GetDownloadUrlForLayer",
|
|
302
|
-
"ecr:BatchGetImage",
|
|
303
|
-
"ecr:BatchCheckLayerAvailability",
|
|
304
|
-
"ecr:PutImage",
|
|
305
|
-
"ecr:InitiateLayerUpload",
|
|
306
|
-
"ecr:UploadLayerPart",
|
|
307
|
-
"ecr:CompleteLayerUpload"
|
|
308
|
-
]
|
|
309
|
-
}
|
|
310
|
-
]
|
|
311
|
-
})
|
|
312
|
-
}
|
|
313
295
|
|
|
314
296
|
# IAM Role for Agent Core Runtime
|
|
315
297
|
resource "aws_iam_role" "agent_core_runtime_role" {
|
|
@@ -348,27 +330,6 @@ resource "aws_iam_policy" "agent_core_runtime_policy" {
|
|
|
348
330
|
policy = jsonencode({
|
|
349
331
|
Version = "2012-10-17"
|
|
350
332
|
Statement = concat([
|
|
351
|
-
{
|
|
352
|
-
Sid = "ECRImageAccess"
|
|
353
|
-
Effect = "Allow"
|
|
354
|
-
Action = [
|
|
355
|
-
"ecr:BatchGetImage",
|
|
356
|
-
"ecr:GetDownloadUrlForLayer"
|
|
357
|
-
]
|
|
358
|
-
Resource = [
|
|
359
|
-
aws_ecr_repository.agent_core_repository.arn
|
|
360
|
-
]
|
|
361
|
-
},
|
|
362
|
-
{
|
|
363
|
-
Sid = "ECRTokenAccess"
|
|
364
|
-
Effect = "Allow"
|
|
365
|
-
Action = [
|
|
366
|
-
"ecr:GetAuthorizationToken"
|
|
367
|
-
]
|
|
368
|
-
Resource = [
|
|
369
|
-
"*"
|
|
370
|
-
]
|
|
371
|
-
},
|
|
372
333
|
{
|
|
373
334
|
"Effect" : "Allow",
|
|
374
335
|
"Action" : [
|
|
@@ -443,46 +404,6 @@ resource "aws_iam_role_policy_attachment" "agent_core_policy" {
|
|
|
443
404
|
policy_arn = aws_iam_policy.agent_core_runtime_policy.arn
|
|
444
405
|
}
|
|
445
406
|
|
|
446
|
-
# Data source to get container image digest
|
|
447
|
-
data "external" "docker_digest" {
|
|
448
|
-
program = ["sh", "-c", "echo '{\\"digest\\":\\"'$(docker inspect \${var.docker_image_tag} --format '{{.Id}}')'\\"}' "]
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
locals {
|
|
452
|
-
# Content-based, immutable image tag derived from the local image digest
|
|
453
|
-
image_tag = replace(data.external.docker_digest.result.digest, "sha256:", "")
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
# Null resource for container image publish
|
|
457
|
-
resource "null_resource" "docker_publish" {
|
|
458
|
-
triggers = {
|
|
459
|
-
docker_digest = data.external.docker_digest.result.digest
|
|
460
|
-
repository_url = aws_ecr_repository.agent_core_repository.repository_url
|
|
461
|
-
docker_image_tag = var.docker_image_tag
|
|
462
|
-
image_tag = local.image_tag
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
provisioner "local-exec" {
|
|
466
|
-
command = <<-EOT
|
|
467
|
-
# Get ECR login token
|
|
468
|
-
aws ecr get-login-password --region "$AWS_REGION" | docker login --username AWS --password-stdin "$REPOSITORY_URL"
|
|
469
|
-
|
|
470
|
-
# Tag the image with the immutable content-based tag
|
|
471
|
-
docker tag "$DOCKER_IMAGE_TAG" "$REPOSITORY_URL:$IMAGE_TAG"
|
|
472
|
-
|
|
473
|
-
# Push the image
|
|
474
|
-
docker push "$REPOSITORY_URL:$IMAGE_TAG"
|
|
475
|
-
EOT
|
|
476
|
-
environment = {
|
|
477
|
-
AWS_REGION = local.aws_region
|
|
478
|
-
REPOSITORY_URL = self.triggers.repository_url
|
|
479
|
-
DOCKER_IMAGE_TAG = self.triggers.docker_image_tag
|
|
480
|
-
IMAGE_TAG = self.triggers.image_tag
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
depends_on = [aws_ecr_repository_policy.agent_core_ecr_policy]
|
|
485
|
-
}
|
|
486
407
|
|
|
487
408
|
# Security group for the agent core runtime, used when running inside a VPC
|
|
488
409
|
resource "aws_security_group" "agent_core_runtime" {
|
|
@@ -513,8 +434,26 @@ resource "aws_bedrockagentcore_agent_runtime" "agent_runtime" {
|
|
|
513
434
|
role_arn = aws_iam_role.agent_core_runtime_role.arn
|
|
514
435
|
|
|
515
436
|
agent_runtime_artifact {
|
|
516
|
-
container_configuration {
|
|
517
|
-
|
|
437
|
+
dynamic "container_configuration" {
|
|
438
|
+
for_each = var.container_configuration != null ? [var.container_configuration] : []
|
|
439
|
+
content {
|
|
440
|
+
container_uri = container_configuration.value.container_uri
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
dynamic "code_configuration" {
|
|
445
|
+
for_each = var.code_configuration != null ? [var.code_configuration] : []
|
|
446
|
+
content {
|
|
447
|
+
entry_point = code_configuration.value.entry_point
|
|
448
|
+
runtime = code_configuration.value.runtime
|
|
449
|
+
|
|
450
|
+
code {
|
|
451
|
+
s3 {
|
|
452
|
+
bucket = code_configuration.value.s3_bucket
|
|
453
|
+
prefix = code_configuration.value.s3_key
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
}
|
|
518
457
|
}
|
|
519
458
|
}
|
|
520
459
|
|
|
@@ -558,7 +497,7 @@ resource "aws_bedrockagentcore_agent_runtime" "agent_runtime" {
|
|
|
558
497
|
tags = var.tags
|
|
559
498
|
|
|
560
499
|
depends_on = [
|
|
561
|
-
|
|
500
|
+
var.artifact_dependencies,
|
|
562
501
|
aws_iam_role_policy_attachment.agent_core_policy
|
|
563
502
|
]
|
|
564
503
|
}
|
|
@@ -575,7 +514,7 @@ resource "null_resource" "runtime_ready" {
|
|
|
575
514
|
|
|
576
515
|
provisioner "local-exec" {
|
|
577
516
|
command = <<-EOT
|
|
578
|
-
uv run --with boto3==1.43.
|
|
517
|
+
uv run --with boto3==1.43.83 python -c "
|
|
579
518
|
import boto3
|
|
580
519
|
import json
|
|
581
520
|
import os
|
|
@@ -716,15 +655,27 @@ variable "appconfig_application_id" {
|
|
|
716
655
|
type = string
|
|
717
656
|
}
|
|
718
657
|
|
|
658
|
+
variable "asset_ecr_repository_url" {
|
|
659
|
+
description = "URL of the shared asset ECR repository the agent's image is published to. Instantiate the \`core/asset-ecr\` module once per deployment and pass its \`repository_url\` output here."
|
|
660
|
+
type = string
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
variable "asset_ecr_repository_arn" {
|
|
664
|
+
description = "ARN of the shared asset ECR repository (from \`core/asset-ecr.repository_arn\`), used to scope the runtime's image pull grant to it."
|
|
665
|
+
type = string
|
|
666
|
+
}
|
|
667
|
+
|
|
719
668
|
variable "appconfig_application_arn" {
|
|
720
669
|
description = "ARN of the shared runtime-config AppConfig application (from \`core/runtime-config/appconfig.application_arn\`). Used to scope the IAM read permission granted to the agent runtime."
|
|
721
670
|
type = string
|
|
722
671
|
}
|
|
723
672
|
|
|
724
673
|
module "agent_core_runtime" {
|
|
725
|
-
source = "../../../core/agent-core"
|
|
674
|
+
source = "../../../core/agent-core-container"
|
|
726
675
|
agent_runtime_name = "TerraformSnapshotServer"
|
|
727
676
|
docker_image_tag = "proj-terraform-snapshot-server:latest"
|
|
677
|
+
asset_ecr_repository_url = var.asset_ecr_repository_url
|
|
678
|
+
asset_ecr_repository_arn = var.asset_ecr_repository_arn
|
|
728
679
|
server_protocol = "MCP"
|
|
729
680
|
enable_vpc = var.enable_vpc
|
|
730
681
|
vpc_id = var.vpc_id
|
|
@@ -853,7 +804,7 @@ dependencies = [
|
|
|
853
804
|
"aws-lambda-powertools==3.34.0",
|
|
854
805
|
"mcp==1.28.1",
|
|
855
806
|
"uvicorn==0.52.4",
|
|
856
|
-
"boto3==1.43.
|
|
807
|
+
"boto3==1.43.83",
|
|
857
808
|
"aws-opentelemetry-distro==0.19.0"
|
|
858
809
|
]
|
|
859
810
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""AgentCore Runtime entry point.
|
|
2
|
+
|
|
3
|
+
Runs at the root of the deployment package, where the managed runtime executes
|
|
4
|
+
it by file path. The server is imported absolutely so its own relative imports
|
|
5
|
+
resolve.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import uvicorn
|
|
9
|
+
|
|
10
|
+
from <%- moduleName %>.<%- mcpServerNameSnakeCase %>.http import app
|
|
11
|
+
|
|
12
|
+
if __name__ == "__main__":
|
|
13
|
+
uvicorn.run(app, host="0.0.0.0", port=8000)
|
|
@@ -5,12 +5,17 @@
|
|
|
5
5
|
import { type GeneratorCallback, type Tree } from '@nx/devkit';
|
|
6
6
|
import { type NxGeneratorInfo } from '../../utils/nx.js';
|
|
7
7
|
import type { IacMetadata } from '../../utils/shared-constructs-constants.js';
|
|
8
|
-
import type { PyMcpServerGeneratorSchema } from './schema';
|
|
8
|
+
import type { PyMcpServerGeneratorSchema, PyMcpServerInfra } from './schema';
|
|
9
9
|
/** The metadata this generator records, which its predicates read. */
|
|
10
10
|
export interface PyMcpServerMetadata extends IacMetadata {
|
|
11
11
|
readonly port: number;
|
|
12
12
|
readonly rc: string;
|
|
13
13
|
readonly auth: string;
|
|
14
|
+
/**
|
|
15
|
+
* How this component is packaged and hosted, so a consumer can tell a
|
|
16
|
+
* code-packaged runtime from a container-packaged one without re-deriving it.
|
|
17
|
+
*/
|
|
18
|
+
readonly infra: PyMcpServerInfra;
|
|
14
19
|
}
|
|
15
20
|
export declare const DEPENDENCIES: import("../../utils/declared-dependencies.js").DependencyDeclaration<readonly [{
|
|
16
21
|
readonly name: "@modelcontextprotocol/inspector";
|