@aws/nx-plugin 1.0.14 → 1.1.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.
Files changed (40) hide show
  1. package/README.md +1 -0
  2. package/generators.json +8 -0
  3. package/migrations.json +6 -1
  4. package/package.json +1 -1
  5. package/src/internal/test-matrix/generator.js +6 -1
  6. package/src/internal/test-matrix/generator.js.map +1 -1
  7. package/src/migrations/latest/py-agent-pillow-override/metadata.json +3 -0
  8. package/src/migrations/latest/py-agent-pillow-override/migration.d.ts +18 -0
  9. package/src/migrations/latest/py-agent-pillow-override/migration.js +38 -0
  10. package/src/migrations/latest/py-agent-pillow-override/migration.js.map +1 -0
  11. package/src/preset/__snapshots__/generator.spec.ts.snap +2 -0
  12. package/src/sdk/ts.d.ts +2 -0
  13. package/src/sdk/ts.js +2 -0
  14. package/src/sdk/ts.js.map +1 -1
  15. package/src/ts/agent/guardrails/__snapshots__/generator.spec.ts.snap +1625 -0
  16. package/src/ts/agent/guardrails/files/agent/guardrail.json.template +16 -0
  17. package/src/ts/agent/guardrails/files/agent/guardrail.ts.template +86 -0
  18. package/src/ts/agent/guardrails/generator.d.ts +10 -0
  19. package/src/ts/agent/guardrails/generator.js +111 -0
  20. package/src/ts/agent/guardrails/generator.js.map +1 -0
  21. package/src/ts/agent/guardrails/schema.d.js +6 -0
  22. package/src/ts/agent/guardrails/schema.d.js.map +1 -0
  23. package/src/ts/agent/guardrails/schema.d.ts +9 -0
  24. package/src/ts/agent/guardrails/schema.json +25 -0
  25. package/src/utils/guardrail-constructs/files/cdk/app/guardrails/__nameKebabCase__/__nameKebabCase__-guardrail.ts.template +128 -0
  26. package/src/utils/guardrail-constructs/files/terraform/app/guardrails/__nameKebabCase__/__nameKebabCase__-guardrail.tf.template +108 -0
  27. package/src/utils/guardrail-constructs/guardrail-constructs.d.ts +29 -0
  28. package/src/utils/guardrail-constructs/guardrail-constructs.js +52 -0
  29. package/src/utils/guardrail-constructs/guardrail-constructs.js.map +1 -0
  30. package/src/utils/guardrail-constructs/guardrail-wiring.d.ts +35 -0
  31. package/src/utils/guardrail-constructs/guardrail-wiring.js +61 -0
  32. package/src/utils/guardrail-constructs/guardrail-wiring.js.map +1 -0
  33. package/src/utils/nxlv-python.d.ts +1 -0
  34. package/src/utils/nxlv-python.js.map +1 -1
  35. package/src/utils/py.d.ts +10 -0
  36. package/src/utils/py.js +59 -2
  37. package/src/utils/py.js.map +1 -1
  38. package/src/utils/versions.d.ts +8 -0
  39. package/src/utils/versions.js +13 -0
  40. package/src/utils/versions.js.map +1 -1
@@ -0,0 +1,16 @@
1
+ {
2
+ "blockedInputMessaging": "Sorry, I can't help with that request.",
3
+ "blockedOutputsMessaging": "Sorry, I can't share that answer.",
4
+ "deniedTopics": [
5
+ {
6
+ "name": "Investment advice",
7
+ "definition": "Recommendations about which specific stocks, funds or other investments to buy or sell.",
8
+ "examples": ["Which stocks should I buy this year?"]
9
+ }
10
+ ],
11
+ "piiEntities": [
12
+ { "type": "EMAIL", "action": "ANONYMIZE" },
13
+ { "type": "PHONE", "action": "ANONYMIZE" },
14
+ { "type": "US_SOCIAL_SECURITY_NUMBER", "action": "BLOCK" }
15
+ ]
16
+ }
@@ -0,0 +1,86 @@
1
+ import { BedrockModel, type BedrockGuardrailConfig } from '@strands-agents/sdk';
2
+ import {
3
+ type AgentCoreRuntimeConfig,
4
+ getAgentCoreRuntimeConfig,
5
+ } from '<%- agentConnectionImport %>';
6
+
7
+ /**
8
+ * This agent's entry in runtime config, written by the
9
+ * <%- agentNameClassName %>Guardrail construct or the <%- nameKebabCase %> guardrail module.
10
+ */
11
+ interface GuardrailEntry {
12
+ guardrailId?: string;
13
+ guardrailVersion?: string;
14
+ }
15
+
16
+ const RUNTIME_CONFIG_KEY = 'agentcore.guardrails.<%- agentNameClassName %>';
17
+
18
+ let warnedUnguarded = false;
19
+
20
+ const readEntry = async (): Promise<GuardrailEntry | undefined> => {
21
+ const config: AgentCoreRuntimeConfig & {
22
+ guardrails?: Record<string, GuardrailEntry>;
23
+ } = await getAgentCoreRuntimeConfig();
24
+ return config.guardrails?.['<%- agentNameClassName %>'];
25
+ };
26
+
27
+ /**
28
+ * The guardrail to apply, read from runtime config on every model call
29
+ * (cached for 5 seconds).
30
+ */
31
+ const resolveGuardrail = async (): Promise<
32
+ BedrockGuardrailConfig | undefined
33
+ > => {
34
+ const localDev = process.env.LOCAL_DEV === 'true';
35
+ let entry: GuardrailEntry | undefined;
36
+ if (!localDev) {
37
+ entry = await readEntry();
38
+ } else if (process.env.RUNTIME_CONFIG_APP_ID) {
39
+ entry = await readEntry().catch(() => undefined);
40
+ }
41
+
42
+ if (!entry?.guardrailId || !entry.guardrailVersion) {
43
+ if (!localDev) {
44
+ throw new Error(
45
+ `No guardrail for this agent in runtime config at ${RUNTIME_CONFIG_KEY}. Add the <%- agentNameClassName %>Guardrail construct (CDK) or the guardrails/<%- nameKebabCase %> module (Terraform) to your infrastructure.`,
46
+ );
47
+ }
48
+ if (!warnedUnguarded) {
49
+ warnedUnguarded = true;
50
+ console.warn(
51
+ `No guardrail for this agent in runtime config at ${RUNTIME_CONFIG_KEY}, so the agent is running without a guardrail (LOCAL_DEV=true).`,
52
+ );
53
+ }
54
+ return undefined;
55
+ }
56
+
57
+ if (!/^[1-9][0-9]*$/.test(entry.guardrailVersion)) {
58
+ throw new Error(
59
+ `The guardrail version in runtime config at ${RUNTIME_CONFIG_KEY} must be a numbered guardrail version, but is ${entry.guardrailVersion}.`,
60
+ );
61
+ }
62
+
63
+ return {
64
+ guardrailIdentifier: entry.guardrailId,
65
+ guardrailVersion: entry.guardrailVersion,
66
+ trace: 'enabled',
67
+ };
68
+ };
69
+
70
+ /**
71
+ * A Bedrock model that applies this agent's guardrail from runtime config
72
+ * before each model call, so a new guardrail version applies without a
73
+ * restart.
74
+ */
75
+ export class GuardrailedBedrockModel extends BedrockModel {
76
+ override async *stream(...args: Parameters<BedrockModel['stream']>) {
77
+ this.updateConfig({ guardrailConfig: await resolveGuardrail() });
78
+ return yield* super.stream(...args);
79
+ }
80
+ }
81
+
82
+ /**
83
+ * The Bedrock model with this agent's guardrail applied.
84
+ */
85
+ export const getGuardrailedModel = (): BedrockModel =>
86
+ new GuardrailedBedrockModel();
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ import { type GeneratorCallback, type Tree } from '@nx/devkit';
6
+ import { type NxGeneratorInfo } from '../../../utils/nx.js';
7
+ import type { TsAgentGuardrailsGeneratorSchema } from './schema';
8
+ export declare const TS_AGENT_GUARDRAILS_GENERATOR_INFO: NxGeneratorInfo;
9
+ export declare const tsAgentGuardrailsGenerator: (tree: Tree, options: TsAgentGuardrailsGeneratorSchema) => Promise<GeneratorCallback>;
10
+ export default tsAgentGuardrailsGenerator;
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */ import { generateFiles, joinPathFragments, logger, OverwriteStrategy } from "@nx/devkit";
5
+ import { addDestructuredImport, applyGritQL, matchGritQL } from "../../../utils/ast.js";
6
+ import { formatFilesInSubtree } from "../../../utils/format.js";
7
+ import { addGuardrailInfra } from "../../../utils/guardrail-constructs/guardrail-constructs.js";
8
+ import { guardrailWiringMessage } from "../../../utils/guardrail-constructs/guardrail-wiring.js";
9
+ import { addGeneratorMetricsIfApplicable } from "../../../utils/metrics.js";
10
+ import { esmVars, isEsmWorkspace } from "../../../utils/module-format.js";
11
+ import { kebabCase, toClassName } from "../../../utils/names.js";
12
+ import { getNpmScope } from "../../../utils/npm-scope.js";
13
+ import { addComponentGeneratorMetadata, getGeneratorInfo, readProjectConfigurationUnqualified } from "../../../utils/nx.js";
14
+ import { TS_AGENT_GENERATOR_INFO } from "../generator.js";
15
+ export const TS_AGENT_GUARDRAILS_GENERATOR_INFO = getGeneratorInfo(import.meta.filename);
16
+ /**
17
+ * Find the `ts#agent` component to guard, by name when given, otherwise the
18
+ * project's only one.
19
+ */ const resolveAgent = (projectName, components, agent)=>{
20
+ const agents = components.filter((c)=>c.generator === TS_AGENT_GENERATOR_INFO.id);
21
+ const available = agents.map((c)=>c.name).join(', ') || 'none';
22
+ if (agent) {
23
+ const match = agents.find((c)=>c.name === agent);
24
+ if (!match) {
25
+ throw new Error(`No TypeScript Agent named ${agent} in project ${projectName}. Available agents: ${available}`);
26
+ }
27
+ return match;
28
+ }
29
+ if (agents.length !== 1) {
30
+ throw new Error(agents.length === 0 ? `Project ${projectName} has no TypeScript Agent. Add one with the ts#agent generator first.` : `Project ${projectName} has more than one TypeScript Agent. Specify which to guard with --agent. Available agents: ${available}`);
31
+ }
32
+ return agents[0];
33
+ };
34
+ /**
35
+ * Add `model: getGuardrailedModel()` to the `new Agent({...})` call in
36
+ * agent.ts. An agent that already sets its own model is left unchanged, and
37
+ * the lines to add by hand are logged instead.
38
+ */ const addGuardrailedModelToAgent = async (tree, agentFile)=>{
39
+ const guardrailImport = isEsmWorkspace(tree) ? './guardrail.js' : './guardrail';
40
+ if (tree.exists(agentFile)) {
41
+ if (await matchGritQL(tree, agentFile, '`getGuardrailedModel()`')) {
42
+ return;
43
+ }
44
+ if (await applyGritQL(tree, agentFile, '`new Agent({ $props })` => `new Agent({ model: getGuardrailedModel(), $props })` where { $props <: not some or { `model: $_`, `model` } }')) {
45
+ await addDestructuredImport(tree, agentFile, [
46
+ 'getGuardrailedModel'
47
+ ], './guardrail.js');
48
+ return;
49
+ }
50
+ }
51
+ logger.warn(`Could not add the guardrail to ${agentFile}, because ${tree.exists(agentFile) ? 'its new Agent({...}) call already sets a model or is not an inline object' : 'the file does not exist'}. Set the model of your Agent to the guardrailed model by hand:
52
+
53
+ model: getGuardrailedModel(),
54
+
55
+ and import it:
56
+
57
+ import { getGuardrailedModel } from '${guardrailImport}';`);
58
+ };
59
+ export const tsAgentGuardrailsGenerator = async (tree, options)=>{
60
+ const project = readProjectConfigurationUnqualified(tree, options.project);
61
+ const agent = resolveAgent(project.name, project.metadata?.components ?? [], options.agent);
62
+ const agentTargetPrefix = agent.name ?? 'agent';
63
+ const agentNameClassName = agent.rc ?? toClassName(agentTargetPrefix);
64
+ const nameKebabCase = kebabCase(agentNameClassName);
65
+ const agentPath = agent.path ?? joinPathFragments('src', agentTargetPrefix);
66
+ const agentDir = joinPathFragments(project.root, agentPath);
67
+ // The policy is the user's to edit, so a re-run never touches these files.
68
+ generateFiles(tree, joinPathFragments(import.meta.dirname, 'files', 'agent'), agentDir, {
69
+ ...esmVars(tree),
70
+ agentConnectionImport: `@${getNpmScope(tree)}/agent-connection`,
71
+ agentNameClassName,
72
+ nameKebabCase
73
+ }, {
74
+ overwriteStrategy: OverwriteStrategy.KeepExisting
75
+ });
76
+ await addGuardrailedModelToAgent(tree, joinPathFragments(agentDir, 'agent.ts'));
77
+ const iac = agent.iac;
78
+ let wiringMessage;
79
+ if (iac) {
80
+ await addGuardrailInfra(tree, {
81
+ iac,
82
+ nameClassName: agentNameClassName,
83
+ nameKebabCase,
84
+ policyPath: joinPathFragments(agentDir, 'guardrail.json')
85
+ });
86
+ wiringMessage = guardrailWiringMessage({
87
+ iac,
88
+ nameClassName: agentNameClassName,
89
+ nameKebabCase,
90
+ npmScope: getNpmScope(tree)
91
+ });
92
+ } else {
93
+ logger.warn(`Agent ${agentTargetPrefix} in project ${project.name} has no infrastructure, so no guardrail infrastructure was generated. Create the guardrail yourself and write its ID and version to runtime config at agentcore.guardrails.${agentNameClassName} as { guardrailId, guardrailVersion }.`);
94
+ }
95
+ addComponentGeneratorMetadata(tree, project.name, TS_AGENT_GUARDRAILS_GENERATOR_INFO, agentPath, agentTargetPrefix);
96
+ await addGeneratorMetricsIfApplicable(tree, [
97
+ TS_AGENT_GUARDRAILS_GENERATOR_INFO
98
+ ]);
99
+ await formatFilesInSubtree(tree);
100
+ // Printed from the callback so it appears after Nx lists the changed
101
+ // files, on every run, since the generator cannot tell whether the stack is
102
+ // already wired.
103
+ return ()=>{
104
+ if (wiringMessage) {
105
+ logger.info(wiringMessage);
106
+ }
107
+ };
108
+ };
109
+ export default tsAgentGuardrailsGenerator;
110
+
111
+ //# sourceMappingURL=generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../packages/nx-plugin/src/ts/agent/guardrails/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 logger,\n OverwriteStrategy,\n type Tree,\n} from '@nx/devkit';\nimport {\n addDestructuredImport,\n applyGritQL,\n matchGritQL,\n} from '../../../utils/ast.js';\nimport { formatFilesInSubtree } from '../../../utils/format.js';\nimport { addGuardrailInfra } from '../../../utils/guardrail-constructs/guardrail-constructs.js';\nimport { guardrailWiringMessage } from '../../../utils/guardrail-constructs/guardrail-wiring.js';\nimport type { Iac } from '../../../utils/iac.js';\nimport { addGeneratorMetricsIfApplicable } from '../../../utils/metrics.js';\nimport { esmVars, isEsmWorkspace } from '../../../utils/module-format.js';\nimport { kebabCase, toClassName } from '../../../utils/names.js';\nimport { getNpmScope } from '../../../utils/npm-scope.js';\nimport {\n addComponentGeneratorMetadata,\n type ComponentMetadata,\n getGeneratorInfo,\n type NxGeneratorInfo,\n readProjectConfigurationUnqualified,\n} from '../../../utils/nx.js';\nimport { TS_AGENT_GENERATOR_INFO } from '../generator.js';\nimport type { TsAgentGuardrailsGeneratorSchema } from './schema';\n\nexport const TS_AGENT_GUARDRAILS_GENERATOR_INFO: NxGeneratorInfo =\n getGeneratorInfo(import.meta.filename);\n\n/**\n * Find the `ts#agent` component to guard, by name when given, otherwise the\n * project's only one.\n */\nconst resolveAgent = (\n projectName: string,\n components: ComponentMetadata[],\n agent?: string,\n): ComponentMetadata => {\n const agents = components.filter(\n (c) => c.generator === TS_AGENT_GENERATOR_INFO.id,\n );\n const available = agents.map((c) => c.name).join(', ') || 'none';\n if (agent) {\n const match = agents.find((c) => c.name === agent);\n if (!match) {\n throw new Error(\n `No TypeScript Agent named ${agent} in project ${projectName}. Available agents: ${available}`,\n );\n }\n return match;\n }\n if (agents.length !== 1) {\n throw new Error(\n agents.length === 0\n ? `Project ${projectName} has no TypeScript Agent. Add one with the ts#agent generator first.`\n : `Project ${projectName} has more than one TypeScript Agent. Specify which to guard with --agent. Available agents: ${available}`,\n );\n }\n return agents[0];\n};\n\n/**\n * Add `model: getGuardrailedModel()` to the `new Agent({...})` call in\n * agent.ts. An agent that already sets its own model is left unchanged, and\n * the lines to add by hand are logged instead.\n */\nconst addGuardrailedModelToAgent = async (\n tree: Tree,\n agentFile: string,\n): Promise<void> => {\n const guardrailImport = isEsmWorkspace(tree)\n ? './guardrail.js'\n : './guardrail';\n\n if (tree.exists(agentFile)) {\n if (await matchGritQL(tree, agentFile, '`getGuardrailedModel()`')) {\n return;\n }\n if (\n await applyGritQL(\n tree,\n agentFile,\n '`new Agent({ $props })` => `new Agent({ model: getGuardrailedModel(), $props })` where { $props <: not some or { `model: $_`, `model` } }',\n )\n ) {\n await addDestructuredImport(\n tree,\n agentFile,\n ['getGuardrailedModel'],\n './guardrail.js',\n );\n return;\n }\n }\n\n logger.warn(\n `Could not add the guardrail to ${agentFile}, because ${tree.exists(agentFile) ? 'its new Agent({...}) call already sets a model or is not an inline object' : 'the file does not exist'}. Set the model of your Agent to the guardrailed model by hand:\n\n model: getGuardrailedModel(),\n\nand import it:\n\n import { getGuardrailedModel } from '${guardrailImport}';`,\n );\n};\n\nexport const tsAgentGuardrailsGenerator = async (\n tree: Tree,\n options: TsAgentGuardrailsGeneratorSchema,\n): Promise<GeneratorCallback> => {\n const project = readProjectConfigurationUnqualified(tree, options.project);\n const agent = resolveAgent(\n project.name,\n (project.metadata as any)?.components ?? [],\n options.agent,\n );\n\n const agentTargetPrefix = agent.name ?? 'agent';\n const agentNameClassName = agent.rc ?? toClassName(agentTargetPrefix);\n const nameKebabCase = kebabCase(agentNameClassName);\n const agentPath = agent.path ?? joinPathFragments('src', agentTargetPrefix);\n const agentDir = joinPathFragments(project.root, agentPath);\n\n // The policy is the user's to edit, so a re-run never touches these files.\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files', 'agent'),\n agentDir,\n {\n ...esmVars(tree),\n agentConnectionImport: `@${getNpmScope(tree)}/agent-connection`,\n agentNameClassName,\n nameKebabCase,\n },\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n\n await addGuardrailedModelToAgent(\n tree,\n joinPathFragments(agentDir, 'agent.ts'),\n );\n\n const iac = agent.iac as Iac | undefined;\n let wiringMessage: string | undefined;\n if (iac) {\n await addGuardrailInfra(tree, {\n iac,\n nameClassName: agentNameClassName,\n nameKebabCase,\n policyPath: joinPathFragments(agentDir, 'guardrail.json'),\n });\n wiringMessage = guardrailWiringMessage({\n iac,\n nameClassName: agentNameClassName,\n nameKebabCase,\n npmScope: getNpmScope(tree),\n });\n } else {\n logger.warn(\n `Agent ${agentTargetPrefix} in project ${project.name} has no infrastructure, so no guardrail infrastructure was generated. Create the guardrail yourself and write its ID and version to runtime config at agentcore.guardrails.${agentNameClassName} as { guardrailId, guardrailVersion }.`,\n );\n }\n\n addComponentGeneratorMetadata(\n tree,\n project.name,\n TS_AGENT_GUARDRAILS_GENERATOR_INFO,\n agentPath,\n agentTargetPrefix,\n );\n\n await addGeneratorMetricsIfApplicable(tree, [\n TS_AGENT_GUARDRAILS_GENERATOR_INFO,\n ]);\n\n await formatFilesInSubtree(tree);\n\n // Printed from the callback so it appears after Nx lists the changed\n // files, on every run, since the generator cannot tell whether the stack is\n // already wired.\n return () => {\n if (wiringMessage) {\n logger.info(wiringMessage);\n }\n };\n};\n\nexport default tsAgentGuardrailsGenerator;\n"],"names":["generateFiles","joinPathFragments","logger","OverwriteStrategy","addDestructuredImport","applyGritQL","matchGritQL","formatFilesInSubtree","addGuardrailInfra","guardrailWiringMessage","addGeneratorMetricsIfApplicable","esmVars","isEsmWorkspace","kebabCase","toClassName","getNpmScope","addComponentGeneratorMetadata","getGeneratorInfo","readProjectConfigurationUnqualified","TS_AGENT_GENERATOR_INFO","TS_AGENT_GUARDRAILS_GENERATOR_INFO","filename","resolveAgent","projectName","components","agent","agents","filter","c","generator","id","available","map","name","join","match","find","Error","length","addGuardrailedModelToAgent","tree","agentFile","guardrailImport","exists","warn","tsAgentGuardrailsGenerator","options","project","metadata","agentTargetPrefix","agentNameClassName","rc","nameKebabCase","agentPath","path","agentDir","root","dirname","agentConnectionImport","overwriteStrategy","KeepExisting","iac","wiringMessage","nameClassName","policyPath","npmScope","info"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */ export { };
5
+
6
+ //# sourceMappingURL=schema.d.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../packages/nx-plugin/src/ts/agent/guardrails/schema.d.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nexport interface TsAgentGuardrailsGeneratorSchema {\n project: string;\n agent?: string;\n}\n"],"names":[],"mappings":"AAAA;;;CAGC,GAED,WAGC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ export interface TsAgentGuardrailsGeneratorSchema {
7
+ project: string;
8
+ agent?: string;
9
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "$schema": "https://json-schema.org/schema",
3
+ "$id": "ts#agent#guardrails",
4
+ "title": "ts#agent#guardrails",
5
+ "x-label": "Agent Guardrails",
6
+ "description": "Add an Amazon Bedrock Guardrail to a TypeScript Agent",
7
+ "type": "object",
8
+ "properties": {
9
+ "project": {
10
+ "type": "string",
11
+ "description": "The project containing the TypeScript Agent",
12
+ "$default": {
13
+ "$source": "argv",
14
+ "index": 0
15
+ },
16
+ "x-prompt": "Select the project containing the TypeScript Agent to guard",
17
+ "x-dropdown": "projects"
18
+ },
19
+ "agent": {
20
+ "type": "string",
21
+ "description": "The name of the Agent component to guard. Required when the project contains more than one TypeScript Agent."
22
+ }
23
+ },
24
+ "required": ["project"]
25
+ }
@@ -0,0 +1,128 @@
1
+ import { createHash } from 'node:crypto';
2
+ import * as fs from 'node:fs';
3
+ import * as path from 'node:path';
4
+ import * as url from 'node:url';
5
+ import { CfnOutput, Names, Stack } from 'aws-cdk-lib';
6
+ import * as bedrock from 'aws-cdk-lib/aws-bedrock';
7
+ import * as iam from 'aws-cdk-lib/aws-iam';
8
+ import { Construct } from 'constructs';
9
+ import { RuntimeConfig } from '../../../core/runtime-config<% if (esm) { %>.js<% } %>';
10
+ import { findWorkspaceRoot } from '../../../core/workspace<% if (esm) { %>.js<% } %>';
11
+
12
+ interface GuardrailPolicy {
13
+ blockedInputMessaging: string;
14
+ blockedOutputsMessaging: string;
15
+ deniedTopics?: { name: string; definition: string; examples?: string[] }[];
16
+ piiEntities?: { type: string; action: string }[];
17
+ }
18
+
19
+ // Read at synth time, anchored on the workspace root so it still resolves once
20
+ // this file compiles to dist/.
21
+ const policyFile = fs.readFileSync(
22
+ path.join(
23
+ findWorkspaceRoot(url.fileURLToPath(new URL(<% if (esm) { %>import.meta.url<% } else { %>require('url').pathToFileURL(__filename).href<% } %>))),
24
+ '<%- policyPath %>',
25
+ ),
26
+ );
27
+ const policy: GuardrailPolicy = JSON.parse(policyFile.toString('utf-8'));
28
+
29
+ /**
30
+ * Properties for the <%- nameClassName %>Guardrail. Any CfnGuardrail property
31
+ * supplied here takes precedence over guardrail.json.
32
+ */
33
+ export type <%- nameClassName %>GuardrailProps = Partial<bedrock.CfnGuardrailProps> & {
34
+ /** The agent that applies this guardrail. It is granted bedrock:ApplyGuardrail. */
35
+ readonly agent: iam.IGrantable;
36
+ };
37
+
38
+ /**
39
+ * An Amazon Bedrock Guardrail for <%- nameClassName %>, with a numbered version
40
+ * that changes whenever its rules change. Its ID and version are written to
41
+ * runtime config, where the agent reads them.
42
+ */
43
+ export class <%- nameClassName %>Guardrail extends Construct {
44
+ public readonly guardrail: bedrock.CfnGuardrail;
45
+ public readonly version: bedrock.CfnGuardrailVersion;
46
+ public readonly guardrailId: string;
47
+ public readonly guardrailArn: string;
48
+ public readonly guardrailVersion: string;
49
+
50
+ constructor(
51
+ scope: Construct,
52
+ id: string,
53
+ props: <%- nameClassName %>GuardrailProps,
54
+ ) {
55
+ super(scope, id);
56
+
57
+ const { agent, ...overrides } = props;
58
+
59
+ const deniedTopics = policy.deniedTopics ?? [];
60
+ const piiEntities = policy.piiEntities ?? [];
61
+
62
+ this.guardrail = new bedrock.CfnGuardrail(this, 'Guardrail', {
63
+ name: Names.uniqueResourceName(this, {
64
+ maxLength: 50,
65
+ separator: '-',
66
+ allowedSpecialCharacters: '-_',
67
+ }),
68
+ blockedInputMessaging: policy.blockedInputMessaging,
69
+ blockedOutputsMessaging: policy.blockedOutputsMessaging,
70
+ ...(deniedTopics.length > 0 && {
71
+ topicPolicyConfig: {
72
+ topicsConfig: deniedTopics.map(({ name, definition, examples }) => ({
73
+ name,
74
+ definition,
75
+ examples,
76
+ type: 'DENY',
77
+ })),
78
+ },
79
+ }),
80
+ ...(piiEntities.length > 0 && {
81
+ sensitiveInformationPolicyConfig: {
82
+ piiEntitiesConfig: piiEntities.map(({ type, action }) => ({
83
+ type,
84
+ action,
85
+ })),
86
+ },
87
+ }),
88
+ ...overrides,
89
+ });
90
+
91
+ const hash = createHash('sha256').update(policyFile);
92
+ if (Object.keys(overrides).length > 0) {
93
+ hash.update(JSON.stringify(Stack.of(this).resolve(overrides)));
94
+ }
95
+
96
+ this.version = new bedrock.CfnGuardrailVersion(this, 'Version', {
97
+ guardrailIdentifier: this.guardrail.attrGuardrailId,
98
+ description: `guardrail.json sha256 ${hash.digest('hex')}`,
99
+ });
100
+
101
+ this.guardrailId = this.guardrail.attrGuardrailId;
102
+ this.guardrailArn = this.guardrail.attrGuardrailArn;
103
+ this.guardrailVersion = this.version.attrVersion;
104
+
105
+ new CfnOutput(this, 'GuardrailId', { value: this.guardrailId });
106
+ new CfnOutput(this, 'GuardrailVersion', { value: this.guardrailVersion });
107
+
108
+ const rc = RuntimeConfig.ensure(this);
109
+ rc.set('agentcore', 'guardrails', {
110
+ ...rc.get('agentcore').guardrails,
111
+ <%- nameClassName %>: {
112
+ guardrailId: this.guardrailId,
113
+ guardrailVersion: this.guardrailVersion,
114
+ },
115
+ });
116
+
117
+ this.grantApply(agent);
118
+ }
119
+
120
+ /** Grant permission to apply this guardrail. */
121
+ public grantApply(grantee: iam.IGrantable): iam.Grant {
122
+ return iam.Grant.addToPrincipal({
123
+ grantee,
124
+ actions: ['bedrock:ApplyGuardrail'],
125
+ resourceArns: [this.guardrailArn],
126
+ });
127
+ }
128
+ }
@@ -0,0 +1,108 @@
1
+ terraform {
2
+ required_providers {
3
+ aws = {
4
+ source = "hashicorp/aws"
5
+ version = "<%- awsProviderVersion %>"
6
+ }
7
+ random = {
8
+ source = "hashicorp/random"
9
+ version = "<%- randomProviderVersion %>"
10
+ }
11
+ }
12
+ }
13
+
14
+ variable "tags" {
15
+ description = "Tags to apply to resources"
16
+ type = map(string)
17
+ default = {}
18
+ }
19
+
20
+ locals {
21
+ policy_file = "${path.module}/../../../../../../../<%- policyPath %>"
22
+ policy = jsondecode(file(local.policy_file))
23
+ name_prefix = "<%- guardrailNamePrefix %>"
24
+ }
25
+
26
+ resource "random_id" "unique_suffix" {
27
+ byte_length = 4
28
+ }
29
+
30
+ resource "aws_bedrock_guardrail" "this" {
31
+ name = "${local.name_prefix}-${random_id.unique_suffix.hex}"
32
+ blocked_input_messaging = local.policy.blockedInputMessaging
33
+ blocked_outputs_messaging = local.policy.blockedOutputsMessaging
34
+
35
+ dynamic "topic_policy_config" {
36
+ for_each = length(try(local.policy.deniedTopics, [])) > 0 ? [1] : []
37
+ content {
38
+ dynamic "topics_config" {
39
+ for_each = local.policy.deniedTopics
40
+ content {
41
+ name = topics_config.value.name
42
+ definition = topics_config.value.definition
43
+ examples = try(topics_config.value.examples, [])
44
+ type = "DENY"
45
+ }
46
+ }
47
+ }
48
+ }
49
+
50
+ dynamic "sensitive_information_policy_config" {
51
+ for_each = length(try(local.policy.piiEntities, [])) > 0 ? [1] : []
52
+ content {
53
+ dynamic "pii_entities_config" {
54
+ for_each = local.policy.piiEntities
55
+ content {
56
+ type = pii_entities_config.value.type
57
+ action = pii_entities_config.value.action
58
+ }
59
+ }
60
+ }
61
+ }
62
+
63
+ tags = var.tags
64
+ }
65
+
66
+ resource "aws_bedrock_guardrail_version" "this" {
67
+ guardrail_arn = aws_bedrock_guardrail.this.guardrail_arn
68
+ description = "guardrail.json sha256 ${filesha256(local.policy_file)}"
69
+
70
+ lifecycle {
71
+ create_before_destroy = true
72
+ }
73
+ }
74
+
75
+ module "add_guardrail_to_runtime_config" {
76
+ source = "../../../core/runtime-config/entry"
77
+
78
+ namespace = "agentcore"
79
+ key = "guardrails"
80
+ value = { "<%= nameClassName %>" = { guardrailId = aws_bedrock_guardrail.this.guardrail_id, guardrailVersion = aws_bedrock_guardrail_version.this.version } }
81
+ }
82
+
83
+ output "guardrail_id" {
84
+ description = "ID of the guardrail"
85
+ value = aws_bedrock_guardrail.this.guardrail_id
86
+ }
87
+
88
+ output "guardrail_arn" {
89
+ description = "ARN of the guardrail"
90
+ value = aws_bedrock_guardrail.this.guardrail_arn
91
+ }
92
+
93
+ output "guardrail_version" {
94
+ description = "Numbered version of the guardrail"
95
+ value = aws_bedrock_guardrail_version.this.version
96
+ }
97
+
98
+ output "iam_policy_statements" {
99
+ description = "IAM policy statements that allow the agent to apply the guardrail"
100
+ value = [
101
+ {
102
+ Effect = "Allow"
103
+ Action = ["bedrock:ApplyGuardrail"]
104
+ Resource = [aws_bedrock_guardrail.this.guardrail_arn]
105
+ }
106
+ ]
107
+ depends_on = [module.add_guardrail_to_runtime_config]
108
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ import { type Tree } from '@nx/devkit';
6
+ import type { Iac } from '../iac.js';
7
+ export interface AddGuardrailInfraOptions {
8
+ iac: Iac;
9
+ /** Class name of the guarded agent, eg `MyAgent` gives `MyAgentGuardrail`. */
10
+ nameClassName: string;
11
+ /**
12
+ * Kebab-case name of the guarded agent, used for the directory and, with a
13
+ * `-guardrail` suffix, the file.
14
+ */
15
+ nameKebabCase: string;
16
+ /** Workspace-root-relative path of the guardrail.json policy file. */
17
+ policyPath: string;
18
+ }
19
+ /**
20
+ * Add the Amazon Bedrock Guardrail infrastructure for the selected IaC
21
+ * provider: a CDK construct in the shared constructs project, or a Terraform
22
+ * module in the shared Terraform project. Both read the policy file at synth
23
+ * or plan time.
24
+ *
25
+ * Files are written with `KeepExisting`, so a re-run leaves them unchanged.
26
+ * No build dependency is added on the agent's project, since the
27
+ * infrastructure reads a source file and imports none of the agent's code.
28
+ */
29
+ export declare const addGuardrailInfra: (tree: Tree, options: AddGuardrailInfraOptions) => Promise<void>;
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */ import { generateFiles, joinPathFragments, OverwriteStrategy } from "@nx/devkit";
5
+ import { addStarExport } from "../ast.js";
6
+ import { esmVars } from "../module-format.js";
7
+ import { PACKAGES_DIR, SHARED_CONSTRUCTS_DIR, SHARED_TERRAFORM_DIR } from "../shared-constructs-constants.js";
8
+ import { terraformProviderVersions } from "../versions.js";
9
+ /**
10
+ * Add the Amazon Bedrock Guardrail infrastructure for the selected IaC
11
+ * provider: a CDK construct in the shared constructs project, or a Terraform
12
+ * module in the shared Terraform project. Both read the policy file at synth
13
+ * or plan time.
14
+ *
15
+ * Files are written with `KeepExisting`, so a re-run leaves them unchanged.
16
+ * No build dependency is added on the agent's project, since the
17
+ * infrastructure reads a source file and imports none of the agent's code.
18
+ */ export const addGuardrailInfra = async (tree, options)=>{
19
+ const templateContext = {
20
+ nameClassName: options.nameClassName,
21
+ nameKebabCase: options.nameKebabCase,
22
+ policyPath: options.policyPath
23
+ };
24
+ switch(options.iac){
25
+ case 'cdk':
26
+ {
27
+ const appDir = joinPathFragments(PACKAGES_DIR, SHARED_CONSTRUCTS_DIR, 'src', 'app');
28
+ generateFiles(tree, joinPathFragments(import.meta.dirname, 'files', 'cdk', 'app', 'guardrails'), joinPathFragments(appDir, 'guardrails'), {
29
+ ...templateContext,
30
+ ...esmVars(tree)
31
+ }, {
32
+ overwriteStrategy: OverwriteStrategy.KeepExisting
33
+ });
34
+ await addStarExport(tree, joinPathFragments(appDir, 'guardrails', 'index.ts'), `./${options.nameKebabCase}/${options.nameKebabCase}-guardrail.js`);
35
+ await addStarExport(tree, joinPathFragments(appDir, 'index.ts'), './guardrails/index.js');
36
+ break;
37
+ }
38
+ case 'terraform':
39
+ generateFiles(tree, joinPathFragments(import.meta.dirname, 'files', 'terraform', 'app', 'guardrails'), joinPathFragments(PACKAGES_DIR, SHARED_TERRAFORM_DIR, 'src', 'app', 'guardrails'), {
40
+ ...templateContext,
41
+ // Guardrail names are at most 50 characters: the prefix, a hyphen
42
+ // and the 8 hex characters of the random suffix.
43
+ guardrailNamePrefix: `${options.nameKebabCase}-guardrail`.slice(0, 41),
44
+ ...terraformProviderVersions()
45
+ }, {
46
+ overwriteStrategy: OverwriteStrategy.KeepExisting
47
+ });
48
+ break;
49
+ }
50
+ };
51
+
52
+ //# sourceMappingURL=guardrail-constructs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../packages/nx-plugin/src/utils/guardrail-constructs/guardrail-constructs.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {\n generateFiles,\n joinPathFragments,\n OverwriteStrategy,\n type Tree,\n} from '@nx/devkit';\nimport { addStarExport } from '../ast.js';\nimport type { Iac } from '../iac.js';\nimport { esmVars } from '../module-format.js';\nimport {\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n SHARED_TERRAFORM_DIR,\n} from '../shared-constructs-constants.js';\nimport { terraformProviderVersions } from '../versions.js';\n\nexport interface AddGuardrailInfraOptions {\n iac: Iac;\n /** Class name of the guarded agent, eg `MyAgent` gives `MyAgentGuardrail`. */\n nameClassName: string;\n /**\n * Kebab-case name of the guarded agent, used for the directory and, with a\n * `-guardrail` suffix, the file.\n */\n nameKebabCase: string;\n /** Workspace-root-relative path of the guardrail.json policy file. */\n policyPath: string;\n}\n\n/**\n * Add the Amazon Bedrock Guardrail infrastructure for the selected IaC\n * provider: a CDK construct in the shared constructs project, or a Terraform\n * module in the shared Terraform project. Both read the policy file at synth\n * or plan time.\n *\n * Files are written with `KeepExisting`, so a re-run leaves them unchanged.\n * No build dependency is added on the agent's project, since the\n * infrastructure reads a source file and imports none of the agent's code.\n */\nexport const addGuardrailInfra = async (\n tree: Tree,\n options: AddGuardrailInfraOptions,\n): Promise<void> => {\n const templateContext = {\n nameClassName: options.nameClassName,\n nameKebabCase: options.nameKebabCase,\n policyPath: options.policyPath,\n };\n\n switch (options.iac) {\n case 'cdk': {\n const appDir = joinPathFragments(\n PACKAGES_DIR,\n SHARED_CONSTRUCTS_DIR,\n 'src',\n 'app',\n );\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'cdk',\n 'app',\n 'guardrails',\n ),\n joinPathFragments(appDir, 'guardrails'),\n { ...templateContext, ...esmVars(tree) },\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n await addStarExport(\n tree,\n joinPathFragments(appDir, 'guardrails', 'index.ts'),\n `./${options.nameKebabCase}/${options.nameKebabCase}-guardrail.js`,\n );\n await addStarExport(\n tree,\n joinPathFragments(appDir, 'index.ts'),\n './guardrails/index.js',\n );\n break;\n }\n case 'terraform':\n generateFiles(\n tree,\n joinPathFragments(\n import.meta.dirname,\n 'files',\n 'terraform',\n 'app',\n 'guardrails',\n ),\n joinPathFragments(\n PACKAGES_DIR,\n SHARED_TERRAFORM_DIR,\n 'src',\n 'app',\n 'guardrails',\n ),\n {\n ...templateContext,\n // Guardrail names are at most 50 characters: the prefix, a hyphen\n // and the 8 hex characters of the random suffix.\n guardrailNamePrefix: `${options.nameKebabCase}-guardrail`.slice(\n 0,\n 41,\n ),\n ...terraformProviderVersions(),\n },\n { overwriteStrategy: OverwriteStrategy.KeepExisting },\n );\n break;\n }\n};\n"],"names":["generateFiles","joinPathFragments","OverwriteStrategy","addStarExport","esmVars","PACKAGES_DIR","SHARED_CONSTRUCTS_DIR","SHARED_TERRAFORM_DIR","terraformProviderVersions","addGuardrailInfra","tree","options","templateContext","nameClassName","nameKebabCase","policyPath","iac","appDir","dirname","overwriteStrategy","KeepExisting","guardrailNamePrefix","slice"],"mappings":"AAAA;;;CAGC,GACD,SACEA,aAAa,EACbC,iBAAiB,EACjBC,iBAAiB,QAEZ,aAAa;AACpB,SAASC,aAAa,QAAQ,YAAY;AAE1C,SAASC,OAAO,QAAQ,sBAAsB;AAC9C,SACEC,YAAY,EACZC,qBAAqB,EACrBC,oBAAoB,QACf,oCAAoC;AAC3C,SAASC,yBAAyB,QAAQ,iBAAiB;AAe3D;;;;;;;;;CASC,GACD,OAAO,MAAMC,oBAAoB,OAC/BC,MACAC;IAEA,MAAMC,kBAAkB;QACtBC,eAAeF,QAAQE,aAAa;QACpCC,eAAeH,QAAQG,aAAa;QACpCC,YAAYJ,QAAQI,UAAU;IAChC;IAEA,OAAQJ,QAAQK,GAAG;QACjB,KAAK;YAAO;gBACV,MAAMC,SAAShB,kBACbI,cACAC,uBACA,OACA;gBAEFN,cACEU,MACAT,kBACE,YAAYiB,OAAO,EACnB,SACA,OACA,OACA,eAEFjB,kBAAkBgB,QAAQ,eAC1B;oBAAE,GAAGL,eAAe;oBAAE,GAAGR,QAAQM,KAAK;gBAAC,GACvC;oBAAES,mBAAmBjB,kBAAkBkB,YAAY;gBAAC;gBAEtD,MAAMjB,cACJO,MACAT,kBAAkBgB,QAAQ,cAAc,aACxC,CAAC,EAAE,EAAEN,QAAQG,aAAa,CAAC,CAAC,EAAEH,QAAQG,aAAa,CAAC,aAAa,CAAC;gBAEpE,MAAMX,cACJO,MACAT,kBAAkBgB,QAAQ,aAC1B;gBAEF;YACF;QACA,KAAK;YACHjB,cACEU,MACAT,kBACE,YAAYiB,OAAO,EACnB,SACA,aACA,OACA,eAEFjB,kBACEI,cACAE,sBACA,OACA,OACA,eAEF;gBACE,GAAGK,eAAe;gBAClB,kEAAkE;gBAClE,iDAAiD;gBACjDS,qBAAqB,GAAGV,QAAQG,aAAa,CAAC,UAAU,CAAC,CAACQ,KAAK,CAC7D,GACA;gBAEF,GAAGd,2BAA2B;YAChC,GACA;gBAAEW,mBAAmBjB,kBAAkBkB,YAAY;YAAC;YAEtD;IACJ;AACF,EAAE"}