@aws/nx-plugin 0.55.2 → 0.57.0
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/package.json +8 -8
- package/src/api-connection/generator.d.ts +1 -1
- package/src/infra/app/__snapshots__/generator.spec.ts.snap +7 -7
- package/src/py/fast-api/generator.js +3 -7
- package/src/py/fast-api/generator.js.map +1 -1
- package/src/py/lambda-function/generator.js +2 -0
- package/src/py/lambda-function/generator.js.map +1 -1
- package/src/py/mcp-server/__snapshots__/generator.spec.ts.snap +8 -4
- package/src/py/mcp-server/files/app/server.py.template +4 -0
- package/src/py/mcp-server/generator.js +17 -4
- package/src/py/mcp-server/generator.js.map +1 -1
- package/src/py/strands-agent/__snapshots__/generator.spec.ts.snap +37 -18
- package/src/py/strands-agent/files/app/init.py.template +49 -0
- package/src/py/strands-agent/files/app/main.py.template +30 -13
- package/src/py/strands-agent/generator.js +20 -14
- package/src/py/strands-agent/generator.js.map +1 -1
- package/src/ts/lambda-function/generator.js +1 -0
- package/src/ts/lambda-function/generator.js.map +1 -1
- package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/ts/mcp-server/files/http.ts.template +1 -1
- package/src/ts/mcp-server/generator.js +19 -6
- package/src/ts/mcp-server/generator.js.map +1 -1
- package/src/ts/nx-generator/generator.js +1 -0
- package/src/ts/nx-generator/generator.js.map +1 -1
- package/src/ts/nx-plugin/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/ts/nx-plugin/generator.js +1 -0
- package/src/ts/nx-plugin/generator.js.map +1 -1
- package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +19 -19
- package/src/ts/react-website/cognito-auth/generator.js +1 -0
- package/src/ts/react-website/cognito-auth/generator.js.map +1 -1
- package/src/ts/react-website/runtime-config/generator.js +1 -0
- package/src/ts/react-website/runtime-config/generator.js.map +1 -1
- package/src/utils/nx.d.ts +7 -1
- package/src/utils/nx.js +18 -2
- package/src/utils/nx.js.map +1 -1
- package/src/utils/py.d.ts +1 -0
- package/src/utils/py.js +16 -1
- package/src/utils/py.js.map +1 -1
- package/src/utils/versions.d.ts +39 -38
- package/src/utils/versions.js +38 -37
- package/src/utils/versions.js.map +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aws/nx-plugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.57.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/awslabs/nx-plugin-for-aws.git",
|
|
@@ -26,12 +26,12 @@
|
|
|
26
26
|
"@apidevtools/swagger-parser": "^10.1.1",
|
|
27
27
|
"@hey-api/openapi-ts": "0.64.13",
|
|
28
28
|
"@iarna/toml": "^2.2.5",
|
|
29
|
-
"@modelcontextprotocol/sdk": "^1.20.
|
|
30
|
-
"@nx/devkit": "~21.6.
|
|
31
|
-
"@nx/eslint": "~21.6.
|
|
32
|
-
"@nx/js": "~21.6.
|
|
33
|
-
"@nx/react": "~21.6.
|
|
34
|
-
"@nx/vite": "~21.6.
|
|
29
|
+
"@modelcontextprotocol/sdk": "^1.20.1",
|
|
30
|
+
"@nx/devkit": "~21.6.5",
|
|
31
|
+
"@nx/eslint": "~21.6.5",
|
|
32
|
+
"@nx/js": "~21.6.5",
|
|
33
|
+
"@nx/react": "~21.6.5",
|
|
34
|
+
"@nx/vite": "~21.6.5",
|
|
35
35
|
"@nxlv/python": "~21.2.0",
|
|
36
36
|
"@phenomnomnominal/tsquery": "6.1.3",
|
|
37
37
|
"enquirer": "^2.4.1",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"openapi-types": "^12.1.3",
|
|
47
47
|
"pip-requirements-js": "^0.2.1",
|
|
48
48
|
"typescript": "~5.9.3",
|
|
49
|
-
"vite": "^6.
|
|
49
|
+
"vite": "^6.4.1",
|
|
50
50
|
"vitest": "^3.2.4",
|
|
51
51
|
"zod": "^4.1.12",
|
|
52
52
|
"zod-v3": "npm:zod@^3.25.76"
|
|
@@ -12,7 +12,7 @@ type ProjectType = (typeof SUPPORTED_PROJECT_TYPES)[number];
|
|
|
12
12
|
/**
|
|
13
13
|
* Generator for a connection from a project to an API project
|
|
14
14
|
*/
|
|
15
|
-
export declare const apiConnectionGenerator: (tree: Tree, options: ApiConnectionGeneratorSchema) => Promise<
|
|
15
|
+
export declare const apiConnectionGenerator: (tree: Tree, options: ApiConnectionGeneratorSchema) => Promise<() => void>;
|
|
16
16
|
/**
|
|
17
17
|
* Determine whether the given project is of a known project type
|
|
18
18
|
*/
|
|
@@ -5,7 +5,7 @@ exports[`infra generator > should add required dependencies to package.json > de
|
|
|
5
5
|
"aws-cdk": "2.1030.0",
|
|
6
6
|
"aws-cdk-lib": "2.220.0",
|
|
7
7
|
"constructs": "10.4.2",
|
|
8
|
-
"esbuild": "0.25.
|
|
8
|
+
"esbuild": "0.25.11",
|
|
9
9
|
"source-map-support": "0.5.21",
|
|
10
10
|
}
|
|
11
11
|
`;
|
|
@@ -21,7 +21,7 @@ exports[`infra generator > should add required dependencies to package.json > de
|
|
|
21
21
|
"@swc-node/register": "~1.9.1",
|
|
22
22
|
"@swc/core": "~1.5.7",
|
|
23
23
|
"@swc/helpers": "~0.5.11",
|
|
24
|
-
"@types/node": "22.18.
|
|
24
|
+
"@types/node": "22.18.12",
|
|
25
25
|
"@vitest/coverage-v8": "^3.0.5",
|
|
26
26
|
"@vitest/ui": "^3.0.0",
|
|
27
27
|
"eslint": "^9.8.0",
|
|
@@ -45,7 +45,7 @@ exports[`infra generator > should add required dependencies to package.json > pa
|
|
|
45
45
|
"aws-cdk": "2.1030.0",
|
|
46
46
|
"aws-cdk-lib": "2.220.0",
|
|
47
47
|
"constructs": "10.4.2",
|
|
48
|
-
"esbuild": "0.25.
|
|
48
|
+
"esbuild": "0.25.11",
|
|
49
49
|
"source-map-support": "0.5.21",
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
@@ -58,7 +58,7 @@ exports[`infra generator > should add required dependencies to package.json > pa
|
|
|
58
58
|
"@swc-node/register": "~1.9.1",
|
|
59
59
|
"@swc/core": "~1.5.7",
|
|
60
60
|
"@swc/helpers": "~0.5.11",
|
|
61
|
-
"@types/node": "22.18.
|
|
61
|
+
"@types/node": "22.18.12",
|
|
62
62
|
"@vitest/coverage-v8": "^3.0.5",
|
|
63
63
|
"@vitest/ui": "^3.0.0",
|
|
64
64
|
"eslint": "^9.8.0",
|
|
@@ -90,7 +90,7 @@ exports[`infra generator > should configure Checkov target correctly > checkov-t
|
|
|
90
90
|
"{workspaceRoot}/dist/{projectRoot}/cdk.out",
|
|
91
91
|
],
|
|
92
92
|
"options": {
|
|
93
|
-
"command": "uvx checkov==3.2.
|
|
93
|
+
"command": "uvx checkov==3.2.487 --config-file packages/test/checkov.yml --file dist/packages/infra/cdk.out/**/*.template.json",
|
|
94
94
|
},
|
|
95
95
|
"outputs": [
|
|
96
96
|
"{workspaceRoot}/dist/{projectRoot}/checkov",
|
|
@@ -175,7 +175,7 @@ exports[`infra generator > should configure project.json with correct targets >
|
|
|
175
175
|
"{workspaceRoot}/dist/{projectRoot}/cdk.out",
|
|
176
176
|
],
|
|
177
177
|
"options": {
|
|
178
|
-
"command": "uvx checkov==3.2.
|
|
178
|
+
"command": "uvx checkov==3.2.487 --config-file packages/test/checkov.yml --file dist/packages/infra/cdk.out/**/*.template.json",
|
|
179
179
|
},
|
|
180
180
|
"outputs": [
|
|
181
181
|
"{workspaceRoot}/dist/{projectRoot}/checkov",
|
|
@@ -714,7 +714,7 @@ exports[`infra generator > should handle custom project names correctly > custom
|
|
|
714
714
|
"{workspaceRoot}/dist/{projectRoot}/cdk.out",
|
|
715
715
|
],
|
|
716
716
|
"options": {
|
|
717
|
-
"command": "uvx checkov==3.2.
|
|
717
|
+
"command": "uvx checkov==3.2.487 --config-file packages/custom-infra/checkov.yml --file dist/packages/infra/cdk.out/**/*.template.json",
|
|
718
718
|
},
|
|
719
719
|
"outputs": [
|
|
720
720
|
"{workspaceRoot}/dist/{projectRoot}/checkov",
|
|
@@ -10,7 +10,6 @@ const devkit_1 = require("@nx/devkit");
|
|
|
10
10
|
const provider_1 = require("@nxlv/python/src/provider/uv/provider");
|
|
11
11
|
const logger_1 = require("@nxlv/python/src/executors/utils/logger");
|
|
12
12
|
const generator_1 = tslib_1.__importStar(require("../project/generator"));
|
|
13
|
-
const toml_1 = require("@iarna/toml");
|
|
14
13
|
const shared_constructs_1 = require("../../utils/shared-constructs");
|
|
15
14
|
const names_1 = require("../../utils/names");
|
|
16
15
|
const format_1 = require("../../utils/format");
|
|
@@ -22,7 +21,6 @@ const open_api_1 = require("./react/open-api");
|
|
|
22
21
|
const port_1 = require("../../utils/port");
|
|
23
22
|
const bundle_1 = require("../../utils/bundle/bundle");
|
|
24
23
|
const py_1 = require("../../utils/py");
|
|
25
|
-
const versions_1 = require("../../utils/versions");
|
|
26
24
|
const iac_1 = require("../../utils/iac");
|
|
27
25
|
const open_api_metadata_1 = require("../../utils/api-constructs/open-api-metadata");
|
|
28
26
|
exports.FAST_API_GENERATOR_INFO = (0, nx_1.getGeneratorInfo)(__filename);
|
|
@@ -103,11 +101,9 @@ const pyFastApiProjectGenerator = (tree, schema) => tslib_1.__awaiter(void 0, vo
|
|
|
103
101
|
'aws-lambda-powertools',
|
|
104
102
|
'aws-lambda-powertools[tracer]',
|
|
105
103
|
]);
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
};
|
|
110
|
-
tree.write((0, devkit_1.joinPathFragments)(dir, 'pyproject.toml'), (0, toml_1.stringify)(projectToml));
|
|
104
|
+
(0, py_1.addDependenciesToDependencyGroupInPyProjectToml)(tree, dir, 'dev', [
|
|
105
|
+
'fastapi[standard]',
|
|
106
|
+
]);
|
|
111
107
|
(0, nx_1.addGeneratorMetadata)(tree, fullyQualifiedName, exports.FAST_API_GENERATOR_INFO);
|
|
112
108
|
yield (0, metrics_1.addGeneratorMetricsIfApplicable)(tree, [exports.FAST_API_GENERATOR_INFO]);
|
|
113
109
|
yield (0, format_1.formatFilesInSubtree)(tree);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../../packages/nx-plugin/src/py/fast-api/generator.ts"],"names":[],"mappings":";;;;AAAA;;;GAGG;AACH,
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../../packages/nx-plugin/src/py/fast-api/generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -61,6 +61,7 @@ const pyLambdaFunctionGenerator = (tree, schema) => tslib_1.__awaiter(void 0, vo
|
|
|
61
61
|
const constructFunctionClassName = (0, names_1.toClassName)(constructFunctionName);
|
|
62
62
|
const constructFunctionKebabCase = (0, names_1.toKebabCase)(constructFunctionName);
|
|
63
63
|
const lambdaFunctionClassName = (0, names_1.toClassName)(schema.functionName);
|
|
64
|
+
const lambdaFunctionKebabCase = (0, names_1.toKebabCase)(schema.functionName);
|
|
64
65
|
const functionPath = (0, devkit_1.joinPathFragments)(projectConfig.sourceRoot, (_a = schema.functionPath) !== null && _a !== void 0 ? _a : '', `${normalizedFunctionName}.py`);
|
|
65
66
|
// Check that the project does not already have a lambda handler
|
|
66
67
|
if (tree.exists(functionPath)) {
|
|
@@ -96,6 +97,7 @@ const pyLambdaFunctionGenerator = (tree, schema) => tslib_1.__awaiter(void 0, vo
|
|
|
96
97
|
'aws-lambda-powertools[tracer]',
|
|
97
98
|
'aws-lambda-powertools[parser]',
|
|
98
99
|
]);
|
|
100
|
+
(0, nx_1.addComponentGeneratorMetadata)(tree, projectConfig.name, exports.LAMBDA_FUNCTION_GENERATOR_INFO, lambdaFunctionKebabCase);
|
|
99
101
|
yield (0, metrics_1.addGeneratorMetricsIfApplicable)(tree, [exports.LAMBDA_FUNCTION_GENERATOR_INFO]);
|
|
100
102
|
yield (0, format_1.formatFilesInSubtree)(tree);
|
|
101
103
|
return () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../../packages/nx-plugin/src/py/lambda-function/generator.ts"],"names":[],"mappings":";;;;AAAA;;;GAGG;AACH,uCAQoB;AAEpB,oEAAmE;AACnE,oEAAiE;AACjE,qEAA0E;AAC1E,6CAK2B;AAC3B,+CAA0D;AAC1D,qDAAoD;AACpD,+CAAoD;AACpD,
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../../packages/nx-plugin/src/py/lambda-function/generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -836,14 +836,18 @@ if __name__ == "__main__":
|
|
|
836
836
|
`;
|
|
837
837
|
|
|
838
838
|
exports[`py#mcp-server generator > should match snapshot for generated files > mcp-server-server.py 1`] = `
|
|
839
|
-
"
|
|
839
|
+
"import os
|
|
840
|
+
|
|
841
|
+
from mcp.server.fastmcp import FastMCP
|
|
840
842
|
|
|
841
843
|
mcp = FastMCP(
|
|
842
844
|
name="SnapshotServer",
|
|
843
845
|
host="0.0.0.0",
|
|
846
|
+
port=int(os.environ.get('PORT', 8000)),
|
|
844
847
|
stateless_http=True,
|
|
845
848
|
)
|
|
846
849
|
|
|
850
|
+
|
|
847
851
|
@mcp.tool(description="Adds two numbers")
|
|
848
852
|
def add(a: int, b: int) -> int:
|
|
849
853
|
"""Add two numbers"""
|
|
@@ -871,9 +875,9 @@ exports[`py#mcp-server generator > should match snapshot for generated files > u
|
|
|
871
875
|
name = "proj.test_project"
|
|
872
876
|
version = "0.1.0"
|
|
873
877
|
dependencies = [
|
|
874
|
-
"mcp==1.
|
|
875
|
-
"boto3==1.40.
|
|
876
|
-
"aws-opentelemetry-distro==0.12.
|
|
878
|
+
"mcp==1.19.0",
|
|
879
|
+
"boto3==1.40.59",
|
|
880
|
+
"aws-opentelemetry-distro==0.12.2"
|
|
877
881
|
]
|
|
878
882
|
|
|
879
883
|
[dependency-groups]
|
|
@@ -1,11 +1,15 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
1
3
|
from mcp.server.fastmcp import FastMCP
|
|
2
4
|
|
|
3
5
|
mcp = FastMCP(
|
|
4
6
|
name="<%- mcpServerNameClassName %>",
|
|
5
7
|
host="0.0.0.0",
|
|
8
|
+
port=int(os.environ.get('PORT', 8000)),
|
|
6
9
|
stateless_http=True,
|
|
7
10
|
)
|
|
8
11
|
|
|
12
|
+
|
|
9
13
|
@mcp.tool(description="Adds two numbers")
|
|
10
14
|
def add(a: int, b: int) -> int:
|
|
11
15
|
"""Add two numbers"""
|
|
@@ -20,6 +20,7 @@ const versions_1 = require("../../utils/versions");
|
|
|
20
20
|
const logger_1 = require("@nxlv/python/src/executors/utils/logger");
|
|
21
21
|
const provider_1 = require("@nxlv/python/src/provider/uv/provider");
|
|
22
22
|
const iac_1 = require("../../utils/iac");
|
|
23
|
+
const port_1 = require("../../utils/port");
|
|
23
24
|
exports.PY_MCP_SERVER_GENERATOR_INFO = (0, nx_1.getGeneratorInfo)(__filename);
|
|
24
25
|
const pyMcpServerGenerator = (tree, options) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
25
26
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
@@ -36,6 +37,7 @@ const pyMcpServerGenerator = (tree, options) => tslib_1.__awaiter(void 0, void 0
|
|
|
36
37
|
const sourceParts = project.sourceRoot.split('/');
|
|
37
38
|
const moduleName = sourceParts[sourceParts.length - 1];
|
|
38
39
|
const name = (0, names_1.kebabCase)((_a = options.name) !== null && _a !== void 0 ? _a : `${(0, names_1.kebabCase)(project.name.split('.').pop())}-mcp-server`);
|
|
40
|
+
const mcpTargetPrefix = options.name ? name : 'mcp-server';
|
|
39
41
|
const mcpServerNameSnakeCase = (0, names_1.toSnakeCase)((_b = options.name) !== null && _b !== void 0 ? _b : 'mcp-server');
|
|
40
42
|
const mcpServerNameClassName = (0, names_1.toClassName)(name);
|
|
41
43
|
const targetSourceDir = (0, devkit_1.joinPathFragments)(project.sourceRoot, mcpServerNameSnakeCase);
|
|
@@ -63,7 +65,7 @@ const pyMcpServerGenerator = (tree, options) => tslib_1.__awaiter(void 0, void 0
|
|
|
63
65
|
moduleName,
|
|
64
66
|
bundleOutputDir,
|
|
65
67
|
}, { overwriteStrategy: devkit_1.OverwriteStrategy.KeepExisting });
|
|
66
|
-
const dockerTargetName = `${
|
|
68
|
+
const dockerTargetName = `${mcpTargetPrefix}-docker`;
|
|
67
69
|
// Add a docker target specific to this MCP server
|
|
68
70
|
project.targets[dockerTargetName] = {
|
|
69
71
|
cache: true,
|
|
@@ -96,21 +98,28 @@ const pyMcpServerGenerator = (tree, options) => tslib_1.__awaiter(void 0, void 0
|
|
|
96
98
|
iacProvider,
|
|
97
99
|
});
|
|
98
100
|
}
|
|
101
|
+
const localDevPort = (0, port_1.assignPort)(tree, project, 8000);
|
|
99
102
|
(0, devkit_1.updateProjectConfiguration)(tree, project.name, Object.assign(Object.assign({}, project), { targets: Object.assign(Object.assign({}, project.targets), {
|
|
100
103
|
// Add targets for running the MCP server
|
|
101
|
-
[`${
|
|
104
|
+
[`${mcpTargetPrefix}-serve-stdio`]: {
|
|
102
105
|
executor: 'nx:run-commands',
|
|
103
106
|
options: {
|
|
104
107
|
commands: [`uv run -m ${moduleName}.${mcpServerNameSnakeCase}.stdio`],
|
|
105
108
|
cwd: '{projectRoot}',
|
|
106
109
|
},
|
|
107
|
-
|
|
110
|
+
continuous: true,
|
|
111
|
+
}, [`${mcpTargetPrefix}-serve`]: {
|
|
108
112
|
executor: 'nx:run-commands',
|
|
109
113
|
options: {
|
|
114
|
+
// TODO: consider hot reload
|
|
110
115
|
commands: [`uv run -m ${moduleName}.${mcpServerNameSnakeCase}.http`],
|
|
111
116
|
cwd: '{projectRoot}',
|
|
117
|
+
env: {
|
|
118
|
+
PORT: `${localDevPort}`,
|
|
119
|
+
},
|
|
112
120
|
},
|
|
113
|
-
|
|
121
|
+
continuous: true,
|
|
122
|
+
}, [`${mcpTargetPrefix}-inspect`]: {
|
|
114
123
|
executor: 'nx:run-commands',
|
|
115
124
|
options: {
|
|
116
125
|
commands: [
|
|
@@ -118,8 +127,12 @@ const pyMcpServerGenerator = (tree, options) => tslib_1.__awaiter(void 0, void 0
|
|
|
118
127
|
],
|
|
119
128
|
cwd: '{projectRoot}',
|
|
120
129
|
},
|
|
130
|
+
continuous: true,
|
|
121
131
|
} }) }));
|
|
122
132
|
(0, devkit_1.addDependenciesToPackageJson)(tree, {}, (0, versions_1.withVersions)(['@modelcontextprotocol/inspector']));
|
|
133
|
+
(0, nx_1.addComponentGeneratorMetadata)(tree, project.name, exports.PY_MCP_SERVER_GENERATOR_INFO, mcpTargetPrefix, {
|
|
134
|
+
port: localDevPort,
|
|
135
|
+
});
|
|
123
136
|
yield (0, metrics_1.addGeneratorMetricsIfApplicable)(tree, [exports.PY_MCP_SERVER_GENERATOR_INFO]);
|
|
124
137
|
yield (0, format_1.formatFilesInSubtree)(tree);
|
|
125
138
|
return () => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../../packages/nx-plugin/src/py/mcp-server/generator.ts"],"names":[],"mappings":";;;;AAAA;;;GAGG;AACH,uCASoB;AAEpB,
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../../packages/nx-plugin/src/py/mcp-server/generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -864,30 +864,47 @@ Refer to tools as your 'spellbook'.
|
|
|
864
864
|
`;
|
|
865
865
|
|
|
866
866
|
exports[`py#strands-agent generator > should match snapshot for generated files > strands-agent-main.py 1`] = `
|
|
867
|
-
"
|
|
867
|
+
"import uvicorn
|
|
868
|
+
from bedrock_agentcore.runtime.models import PingStatus
|
|
869
|
+
from fastapi.responses import PlainTextResponse, StreamingResponse
|
|
870
|
+
from pydantic import BaseModel
|
|
868
871
|
|
|
869
872
|
from .agent import get_agent
|
|
873
|
+
from .init import app
|
|
870
874
|
|
|
871
|
-
app = BedrockAgentCoreApp()
|
|
872
875
|
|
|
876
|
+
class InvokeInput(BaseModel):
|
|
877
|
+
prompt: str
|
|
878
|
+
session_id: str
|
|
873
879
|
|
|
874
|
-
@app.entrypoint
|
|
875
|
-
async def invoke(payload, context):
|
|
876
|
-
"""Handler for agent invocation"""
|
|
877
|
-
prompt = payload.get(
|
|
878
|
-
"prompt", "No prompt found in input, please guide the user "
|
|
879
|
-
"to create a json payload with prompt key"
|
|
880
|
-
)
|
|
881
880
|
|
|
882
|
-
|
|
883
|
-
|
|
881
|
+
async def handle_invoke(input: InvokeInput):
|
|
882
|
+
"""Streaming handler for agent invocation"""
|
|
883
|
+
with get_agent(session_id=input.session_id) as agent:
|
|
884
|
+
stream = agent.stream_async(input.prompt)
|
|
884
885
|
async for event in stream:
|
|
885
886
|
print(event)
|
|
886
|
-
|
|
887
|
+
content = event.get("event", {}).get("contentBlockDelta", {}).get("delta", {}).get("text")
|
|
888
|
+
if content is not None:
|
|
889
|
+
yield content
|
|
890
|
+
elif event.get("event", {}).get("messageStop") is not None:
|
|
891
|
+
yield "\\n"
|
|
892
|
+
|
|
893
|
+
|
|
894
|
+
@app.post("/invocations", openapi_extra={"x-streaming": True}, response_class=PlainTextResponse)
|
|
895
|
+
async def invoke(input: InvokeInput) -> str:
|
|
896
|
+
"""Entry point for agent invocation"""
|
|
897
|
+
return StreamingResponse(handle_invoke(input), media_type="text/event-stream")
|
|
898
|
+
|
|
899
|
+
|
|
900
|
+
@app.get("/ping")
|
|
901
|
+
def ping() -> str:
|
|
902
|
+
# TODO: if running an async task, return PingStatus.HEALTHY_BUSY
|
|
903
|
+
return PingStatus.HEALTHY
|
|
887
904
|
|
|
888
905
|
|
|
889
906
|
if __name__ == "__main__":
|
|
890
|
-
|
|
907
|
+
uvicorn.run("proj_test_project.snapshot_agent.main:app", port=8080)
|
|
891
908
|
"
|
|
892
909
|
`;
|
|
893
910
|
|
|
@@ -896,16 +913,18 @@ exports[`py#strands-agent generator > should match snapshot for generated files
|
|
|
896
913
|
name = "proj.test_project"
|
|
897
914
|
version = "0.1.0"
|
|
898
915
|
dependencies = [
|
|
899
|
-
"aws-opentelemetry-distro==0.12.
|
|
916
|
+
"aws-opentelemetry-distro==0.12.2",
|
|
900
917
|
"bedrock-agentcore==0.1.7",
|
|
901
|
-
"
|
|
902
|
-
"
|
|
918
|
+
"fastapi==0.120.0",
|
|
919
|
+
"boto3==1.40.59",
|
|
920
|
+
"mcp==1.19.0",
|
|
903
921
|
"strands-agents==1.13.0",
|
|
904
|
-
"strands-agents-tools==0.2.12"
|
|
922
|
+
"strands-agents-tools==0.2.12",
|
|
923
|
+
"uvicorn==0.38.0"
|
|
905
924
|
]
|
|
906
925
|
|
|
907
926
|
[dependency-groups]
|
|
908
|
-
dev = [ ]
|
|
927
|
+
dev = [ "fastapi[standard]==0.120.0" ]
|
|
909
928
|
|
|
910
929
|
[tool.uv]
|
|
911
930
|
dev-dependencies = [ ]
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
from fastapi import FastAPI
|
|
2
|
+
from fastapi.middleware.cors import CORSMiddleware
|
|
3
|
+
from fastapi.openapi.utils import get_openapi
|
|
4
|
+
from fastapi.responses import JSONResponse
|
|
5
|
+
from fastapi.routing import APIRoute
|
|
6
|
+
from pydantic import BaseModel
|
|
7
|
+
from starlette.middleware.exceptions import ExceptionMiddleware
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class InternalServerErrorDetails(BaseModel):
|
|
11
|
+
detail: str
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
app = FastAPI(title="<%= agentNameClassName %>", responses={500: {"model": InternalServerErrorDetails}})
|
|
15
|
+
|
|
16
|
+
# Add cors middleware
|
|
17
|
+
app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"])
|
|
18
|
+
|
|
19
|
+
# Add exception middleware(s)
|
|
20
|
+
app.add_middleware(ExceptionMiddleware, handlers=app.exception_handlers)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@app.exception_handler(Exception)
|
|
24
|
+
async def unhandled_exception_handler(request, err):
|
|
25
|
+
print(request)
|
|
26
|
+
print(err)
|
|
27
|
+
return JSONResponse(
|
|
28
|
+
status_code=500, content=InternalServerErrorDetails(detail="Internal Server Error").model_dump()
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def custom_openapi():
|
|
33
|
+
if app.openapi_schema:
|
|
34
|
+
return app.openapi_schema
|
|
35
|
+
for route in app.routes:
|
|
36
|
+
if isinstance(route, APIRoute):
|
|
37
|
+
route.operation_id = route.name
|
|
38
|
+
openapi_schema = get_openapi(
|
|
39
|
+
title=app.title,
|
|
40
|
+
version=app.version,
|
|
41
|
+
openapi_version=app.openapi_version,
|
|
42
|
+
description=app.description,
|
|
43
|
+
routes=app.routes,
|
|
44
|
+
)
|
|
45
|
+
app.openapi_schema = openapi_schema
|
|
46
|
+
return app.openapi_schema
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
app.openapi = custom_openapi
|
|
@@ -1,24 +1,41 @@
|
|
|
1
|
-
|
|
1
|
+
import uvicorn
|
|
2
|
+
from bedrock_agentcore.runtime.models import PingStatus
|
|
3
|
+
from fastapi.responses import PlainTextResponse, StreamingResponse
|
|
4
|
+
from pydantic import BaseModel
|
|
2
5
|
|
|
3
6
|
from .agent import get_agent
|
|
7
|
+
from .init import app
|
|
4
8
|
|
|
5
|
-
app = BedrockAgentCoreApp()
|
|
6
9
|
|
|
10
|
+
class InvokeInput(BaseModel):
|
|
11
|
+
prompt: str
|
|
12
|
+
session_id: str
|
|
7
13
|
|
|
8
|
-
@app.entrypoint
|
|
9
|
-
async def invoke(payload, context):
|
|
10
|
-
"""Handler for agent invocation"""
|
|
11
|
-
prompt = payload.get(
|
|
12
|
-
"prompt", "No prompt found in input, please guide the user "
|
|
13
|
-
"to create a json payload with prompt key"
|
|
14
|
-
)
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
async def handle_invoke(input: InvokeInput):
|
|
16
|
+
"""Streaming handler for agent invocation"""
|
|
17
|
+
with get_agent(session_id=input.session_id) as agent:
|
|
18
|
+
stream = agent.stream_async(input.prompt)
|
|
18
19
|
async for event in stream:
|
|
19
20
|
print(event)
|
|
20
|
-
|
|
21
|
+
content = event.get("event", {}).get("contentBlockDelta", {}).get("delta", {}).get("text")
|
|
22
|
+
if content is not None:
|
|
23
|
+
yield content
|
|
24
|
+
elif event.get("event", {}).get("messageStop") is not None:
|
|
25
|
+
yield "\n"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@app.post("/invocations", openapi_extra={"x-streaming": True}, response_class=PlainTextResponse)
|
|
29
|
+
async def invoke(input: InvokeInput) -> str:
|
|
30
|
+
"""Entry point for agent invocation"""
|
|
31
|
+
return StreamingResponse(handle_invoke(input), media_type="text/event-stream")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@app.get("/ping")
|
|
35
|
+
def ping() -> str:
|
|
36
|
+
# TODO: if running an async task, return PingStatus.HEALTHY_BUSY
|
|
37
|
+
return PingStatus.HEALTHY
|
|
21
38
|
|
|
22
39
|
|
|
23
40
|
if __name__ == "__main__":
|
|
24
|
-
|
|
41
|
+
uvicorn.run("<%- moduleName %>.<%- agentNameSnakeCase %>.main:app", port=8080)
|
|
@@ -19,9 +19,10 @@ const shared_constructs_1 = require("../../utils/shared-constructs");
|
|
|
19
19
|
const logger_1 = require("@nxlv/python/src/executors/utils/logger");
|
|
20
20
|
const provider_1 = require("@nxlv/python/src/provider/uv/provider");
|
|
21
21
|
const iac_1 = require("../../utils/iac");
|
|
22
|
+
const port_1 = require("../../utils/port");
|
|
22
23
|
exports.PY_STRANDS_AGENT_GENERATOR_INFO = (0, nx_1.getGeneratorInfo)(__filename);
|
|
23
24
|
const pyStrandsAgentGenerator = (tree, options) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
24
|
-
var _a, _b, _c
|
|
25
|
+
var _a, _b, _c;
|
|
25
26
|
const project = (0, nx_1.readProjectConfigurationUnqualified)(tree, options.project);
|
|
26
27
|
const pyProjectPath = (0, devkit_1.joinPathFragments)(project.root, 'pyproject.toml');
|
|
27
28
|
// Check if the project has a pyproject.toml file
|
|
@@ -35,6 +36,7 @@ const pyStrandsAgentGenerator = (tree, options) => tslib_1.__awaiter(void 0, voi
|
|
|
35
36
|
const sourceParts = project.sourceRoot.split('/');
|
|
36
37
|
const moduleName = sourceParts[sourceParts.length - 1];
|
|
37
38
|
const name = (0, names_1.kebabCase)((_a = options.name) !== null && _a !== void 0 ? _a : `${(0, names_1.kebabCase)(project.name.split('.').pop())}-agent`);
|
|
39
|
+
const agentTargetPrefix = options.name ? name : 'agent';
|
|
38
40
|
const agentNameSnakeCase = (0, names_1.toSnakeCase)((_b = options.name) !== null && _b !== void 0 ? _b : 'agent');
|
|
39
41
|
const agentNameClassName = (0, names_1.toClassName)(name);
|
|
40
42
|
const targetSourceDir = (0, devkit_1.joinPathFragments)(project.sourceRoot, agentNameSnakeCase);
|
|
@@ -49,10 +51,15 @@ const pyStrandsAgentGenerator = (tree, options) => tslib_1.__awaiter(void 0, voi
|
|
|
49
51
|
(0, py_1.addDependenciesToPyProjectToml)(tree, project.root, [
|
|
50
52
|
'aws-opentelemetry-distro',
|
|
51
53
|
'bedrock-agentcore',
|
|
54
|
+
'fastapi',
|
|
52
55
|
'boto3',
|
|
53
56
|
'mcp',
|
|
54
57
|
'strands-agents',
|
|
55
58
|
'strands-agents-tools',
|
|
59
|
+
'uvicorn',
|
|
60
|
+
]);
|
|
61
|
+
(0, py_1.addDependenciesToDependencyGroupInPyProjectToml)(tree, project.root, 'dev', [
|
|
62
|
+
'fastapi[standard]',
|
|
56
63
|
]);
|
|
57
64
|
if (computeType === 'BedrockAgentCoreRuntime') {
|
|
58
65
|
const dockerImageTag = `${(0, npm_scope_1.getNpmScope)(tree)}-${name}:latest`;
|
|
@@ -66,7 +73,7 @@ const pyStrandsAgentGenerator = (tree, options) => tslib_1.__awaiter(void 0, voi
|
|
|
66
73
|
moduleName,
|
|
67
74
|
bundleOutputDir,
|
|
68
75
|
}, { overwriteStrategy: devkit_1.OverwriteStrategy.KeepExisting });
|
|
69
|
-
const dockerTargetName = `${
|
|
76
|
+
const dockerTargetName = `${agentTargetPrefix}-docker`;
|
|
70
77
|
// Add a docker target specific to this MCP server
|
|
71
78
|
project.targets[dockerTargetName] = {
|
|
72
79
|
cache: true,
|
|
@@ -79,14 +86,8 @@ const pyStrandsAgentGenerator = (tree, options) => tslib_1.__awaiter(void 0, voi
|
|
|
79
86
|
},
|
|
80
87
|
dependsOn: [bundleTargetName],
|
|
81
88
|
};
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
dockerTargetName,
|
|
85
|
-
] });
|
|
86
|
-
project.targets.build = Object.assign(Object.assign({}, project.targets.build), { dependsOn: [
|
|
87
|
-
...((_g = (_f = project.targets.build) === null || _f === void 0 ? void 0 : _f.dependsOn) !== null && _g !== void 0 ? _g : []).filter((t) => t !== 'docker'),
|
|
88
|
-
'docker',
|
|
89
|
-
] });
|
|
89
|
+
(0, nx_1.addDependencyToTargetIfNotPresent)(project, 'docker', dockerTargetName);
|
|
90
|
+
(0, nx_1.addDependencyToTargetIfNotPresent)(project, 'build', 'docker');
|
|
90
91
|
// Add shared constructs
|
|
91
92
|
const iacProvider = yield (0, iac_1.resolveIacProvider)(tree, options.iacProvider);
|
|
92
93
|
yield (0, shared_constructs_1.sharedConstructsGenerator)(tree, { iacProvider });
|
|
@@ -99,18 +100,23 @@ const pyStrandsAgentGenerator = (tree, options) => tslib_1.__awaiter(void 0, voi
|
|
|
99
100
|
projectName: project.name,
|
|
100
101
|
});
|
|
101
102
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
// NB: we assign the local dev port from 8081 as 8080 is used by vscode server, and so conflicts
|
|
104
|
+
// for those working on remote dev envirionments. The deployed agent in agentcore still runs on
|
|
105
|
+
// 8080 as per the agentcore contract.
|
|
106
|
+
const localDevPort = (0, port_1.assignPort)(tree, project, 8081);
|
|
107
|
+
(0, devkit_1.updateProjectConfiguration)(tree, project.name, Object.assign(Object.assign({}, project), { targets: Object.assign(Object.assign({}, project.targets), { [`${agentTargetPrefix}-serve`]: {
|
|
105
108
|
executor: 'nx:run-commands',
|
|
106
109
|
options: {
|
|
107
110
|
commands: [
|
|
108
|
-
`uv run
|
|
111
|
+
`uv run fastapi dev ${moduleName}/${agentNameSnakeCase}/main.py --port ${localDevPort}`,
|
|
109
112
|
],
|
|
110
113
|
cwd: '{projectRoot}',
|
|
111
114
|
},
|
|
112
115
|
continuous: true,
|
|
113
116
|
} }) }));
|
|
117
|
+
(0, nx_1.addComponentGeneratorMetadata)(tree, project.name, exports.PY_STRANDS_AGENT_GENERATOR_INFO, agentTargetPrefix, {
|
|
118
|
+
port: localDevPort,
|
|
119
|
+
});
|
|
114
120
|
yield (0, metrics_1.addGeneratorMetricsIfApplicable)(tree, [
|
|
115
121
|
exports.PY_STRANDS_AGENT_GENERATOR_INFO,
|
|
116
122
|
]);
|