agentcore-cli 0.31.1__py3-none-any.whl
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.
- agentcore/__init__.py +1 -0
- agentcore/agent_inspector/NOTICE +9 -0
- agentcore/agent_inspector/favicon.svg +60 -0
- agentcore/agent_inspector/index.css +1 -0
- agentcore/agent_inspector/index.html +14 -0
- agentcore/agent_inspector/index.js +289 -0
- agentcore/assets/AGENTS.md +60 -0
- agentcore/assets/README.md +108 -0
- agentcore/assets/agents/AGENTS.md +218 -0
- agentcore/assets/cdk/.prettierrc +8 -0
- agentcore/assets/cdk/README.md +26 -0
- agentcore/assets/cdk/bin/cdk.ts +216 -0
- agentcore/assets/cdk/cdk.json +88 -0
- agentcore/assets/cdk/gitignore.template +9 -0
- agentcore/assets/cdk/jest.config.js +9 -0
- agentcore/assets/cdk/lib/cdk-stack.ts +291 -0
- agentcore/assets/cdk/npmignore.template +6 -0
- agentcore/assets/cdk/package.json +30 -0
- agentcore/assets/cdk/test/cdk.test.ts +31 -0
- agentcore/assets/cdk/tsconfig.json +28 -0
- agentcore/assets/container/python/Dockerfile +47 -0
- agentcore/assets/container/python/dockerignore.template +27 -0
- agentcore/assets/container/typescript/Dockerfile +25 -0
- agentcore/assets/container/typescript/dockerignore.template +24 -0
- agentcore/assets/datasets/predefined-v1.jsonl +3 -0
- agentcore/assets/datasets/simulated-v1.jsonl +3 -0
- agentcore/assets/evaluators/autoevals-lambda/execution-role-policy.json +15 -0
- agentcore/assets/evaluators/autoevals-lambda/lambda_function.py +37 -0
- agentcore/assets/evaluators/autoevals-lambda/pyproject.toml +22 -0
- agentcore/assets/evaluators/deepeval-lambda/execution-role-policy.json +15 -0
- agentcore/assets/evaluators/deepeval-lambda/lambda_function.py +29 -0
- agentcore/assets/evaluators/deepeval-lambda/pyproject.toml +19 -0
- agentcore/assets/evaluators/python-lambda/execution-role-policy.json +10 -0
- agentcore/assets/evaluators/python-lambda/lambda_function.py +19 -0
- agentcore/assets/evaluators/python-lambda/pyproject.toml +15 -0
- agentcore/assets/harness/invoke.py.template +74 -0
- agentcore/assets/mcp/python/README.md +27 -0
- agentcore/assets/mcp/python/pyproject.toml +22 -0
- agentcore/assets/mcp/python/server.py +117 -0
- agentcore/assets/mcp/python-lambda/README.md +22 -0
- agentcore/assets/mcp/python-lambda/handler.py +144 -0
- agentcore/assets/mcp/python-lambda/pyproject.toml +15 -0
- agentcore/assets/python/a2a/googleadk/base/README.md +22 -0
- agentcore/assets/python/a2a/googleadk/base/gitignore.template +41 -0
- agentcore/assets/python/a2a/googleadk/base/main.py +124 -0
- agentcore/assets/python/a2a/googleadk/base/model/__init__.py +1 -0
- agentcore/assets/python/a2a/googleadk/base/model/load.py +41 -0
- agentcore/assets/python/a2a/googleadk/base/pyproject.toml +22 -0
- agentcore/assets/python/a2a/langchain_langgraph/base/README.md +22 -0
- agentcore/assets/python/a2a/langchain_langgraph/base/gitignore.template +41 -0
- agentcore/assets/python/a2a/langchain_langgraph/base/main.py +144 -0
- agentcore/assets/python/a2a/langchain_langgraph/base/model/__init__.py +1 -0
- agentcore/assets/python/a2a/langchain_langgraph/base/model/load.py +123 -0
- agentcore/assets/python/a2a/langchain_langgraph/base/pyproject.toml +26 -0
- agentcore/assets/python/a2a/strands/base/README.md +22 -0
- agentcore/assets/python/a2a/strands/base/gitignore.template +41 -0
- agentcore/assets/python/a2a/strands/base/main.py +113 -0
- agentcore/assets/python/a2a/strands/base/model/__init__.py +1 -0
- agentcore/assets/python/a2a/strands/base/model/load.py +123 -0
- agentcore/assets/python/a2a/strands/base/pyproject.toml +23 -0
- agentcore/assets/python/a2a/strands/capabilities/memory/__init__.py +1 -0
- agentcore/assets/python/a2a/strands/capabilities/memory/session.py +46 -0
- agentcore/assets/python/agui/googleadk/base/README.md +30 -0
- agentcore/assets/python/agui/googleadk/base/gitignore.template +41 -0
- agentcore/assets/python/agui/googleadk/base/main.py +91 -0
- agentcore/assets/python/agui/googleadk/base/model/__init__.py +1 -0
- agentcore/assets/python/agui/googleadk/base/model/load.py +41 -0
- agentcore/assets/python/agui/googleadk/base/pyproject.toml +25 -0
- agentcore/assets/python/agui/langchain_langgraph/base/README.md +22 -0
- agentcore/assets/python/agui/langchain_langgraph/base/gitignore.template +41 -0
- agentcore/assets/python/agui/langchain_langgraph/base/main.py +130 -0
- agentcore/assets/python/agui/langchain_langgraph/base/model/__init__.py +1 -0
- agentcore/assets/python/agui/langchain_langgraph/base/model/load.py +123 -0
- agentcore/assets/python/agui/langchain_langgraph/base/pyproject.toml +31 -0
- agentcore/assets/python/agui/strands/base/README.md +22 -0
- agentcore/assets/python/agui/strands/base/gitignore.template +41 -0
- agentcore/assets/python/agui/strands/base/main.py +105 -0
- agentcore/assets/python/agui/strands/base/model/__init__.py +1 -0
- agentcore/assets/python/agui/strands/base/model/load.py +123 -0
- agentcore/assets/python/agui/strands/base/pyproject.toml +27 -0
- agentcore/assets/python/agui/strands/capabilities/memory/__init__.py +1 -0
- agentcore/assets/python/agui/strands/capabilities/memory/session.py +46 -0
- agentcore/assets/python/http/autogen/base/README.md +45 -0
- agentcore/assets/python/http/autogen/base/gitignore.template +41 -0
- agentcore/assets/python/http/autogen/base/main.py +145 -0
- agentcore/assets/python/http/autogen/base/mcp_client/__init__.py +1 -0
- agentcore/assets/python/http/autogen/base/mcp_client/client.py +28 -0
- agentcore/assets/python/http/autogen/base/model/__init__.py +1 -0
- agentcore/assets/python/http/autogen/base/model/load.py +136 -0
- agentcore/assets/python/http/autogen/base/pyproject.toml +34 -0
- agentcore/assets/python/http/bma/base/Dockerfile +41 -0
- agentcore/assets/python/http/bma/base/README.md +178 -0
- agentcore/assets/python/http/bma/base/client.py +200 -0
- agentcore/assets/python/http/bma/base/lifecycle/server.py +641 -0
- agentcore/assets/python/http/bma/base/otel/collector.yaml +69 -0
- agentcore/assets/python/http/bma/base/plugins/acr-report/.codex-plugin/plugin.json +6 -0
- agentcore/assets/python/http/bma/base/plugins/acr-report/skills/acr-report/SKILL.md +16 -0
- agentcore/assets/python/http/bma/base/policies/bma-acr-policy.json +11 -0
- agentcore/assets/python/http/bma/base/policies/bma-session-policy.json +35 -0
- agentcore/assets/python/http/bma/base/policies/bma-session-trust.json +20 -0
- agentcore/assets/python/http/bma/base/pyproject.toml +21 -0
- agentcore/assets/python/http/googleadk/base/README.md +45 -0
- agentcore/assets/python/http/googleadk/base/gitignore.template +41 -0
- agentcore/assets/python/http/googleadk/base/main.py +207 -0
- agentcore/assets/python/http/googleadk/base/mcp_client/__init__.py +1 -0
- agentcore/assets/python/http/googleadk/base/mcp_client/client.py +75 -0
- agentcore/assets/python/http/googleadk/base/model/__init__.py +1 -0
- agentcore/assets/python/http/googleadk/base/model/load.py +41 -0
- agentcore/assets/python/http/googleadk/base/pyproject.toml +24 -0
- agentcore/assets/python/http/langchain_langgraph/base/README.md +45 -0
- agentcore/assets/python/http/langchain_langgraph/base/gitignore.template +41 -0
- agentcore/assets/python/http/langchain_langgraph/base/main.py +227 -0
- agentcore/assets/python/http/langchain_langgraph/base/mcp_client/__init__.py +1 -0
- agentcore/assets/python/http/langchain_langgraph/base/mcp_client/client.py +79 -0
- agentcore/assets/python/http/langchain_langgraph/base/model/__init__.py +1 -0
- agentcore/assets/python/http/langchain_langgraph/base/model/load.py +123 -0
- agentcore/assets/python/http/langchain_langgraph/base/pyproject.toml +38 -0
- agentcore/assets/python/http/openaiagents/base/README.md +45 -0
- agentcore/assets/python/http/openaiagents/base/gitignore.template +41 -0
- agentcore/assets/python/http/openaiagents/base/main.py +200 -0
- agentcore/assets/python/http/openaiagents/base/mcp_client/__init__.py +1 -0
- agentcore/assets/python/http/openaiagents/base/mcp_client/client.py +74 -0
- agentcore/assets/python/http/openaiagents/base/model/__init__.py +1 -0
- agentcore/assets/python/http/openaiagents/base/model/load.py +37 -0
- agentcore/assets/python/http/openaiagents/base/pyproject.toml +21 -0
- agentcore/assets/python/http/strands/base/README.md +46 -0
- agentcore/assets/python/http/strands/base/gitignore.template +41 -0
- agentcore/assets/python/http/strands/base/main.py +714 -0
- agentcore/assets/python/http/strands/base/mcp_client/__init__.py +1 -0
- agentcore/assets/python/http/strands/base/mcp_client/client.py +116 -0
- agentcore/assets/python/http/strands/base/model/__init__.py +1 -0
- agentcore/assets/python/http/strands/base/model/load.py +239 -0
- agentcore/assets/python/http/strands/base/model/mantle_compat.py +21 -0
- agentcore/assets/python/http/strands/base/pyproject.toml +31 -0
- agentcore/assets/python/http/strands/base/skills/fetcher.py +279 -0
- agentcore/assets/python/http/strands/capabilities/execution-limits/hooks/execution_limits.py +54 -0
- agentcore/assets/python/http/strands/capabilities/memory/__init__.py +1 -0
- agentcore/assets/python/http/strands/capabilities/memory/session.py +47 -0
- agentcore/assets/python/http/strands/capabilities/payments/__init__.py +4 -0
- agentcore/assets/python/http/strands/capabilities/payments/payments.py +142 -0
- agentcore/assets/python/mcp/standalone/base/README.md +36 -0
- agentcore/assets/python/mcp/standalone/base/gitignore.template +41 -0
- agentcore/assets/python/mcp/standalone/base/main.py +83 -0
- agentcore/assets/python/mcp/standalone/base/pyproject.toml +16 -0
- agentcore/assets/typescript/.gitkeep +0 -0
- agentcore/assets/typescript/http/strands/base/README.md +42 -0
- agentcore/assets/typescript/http/strands/base/gitignore.template +22 -0
- agentcore/assets/typescript/http/strands/base/main.ts +149 -0
- agentcore/assets/typescript/http/strands/base/mcp_client/client.ts +11 -0
- agentcore/assets/typescript/http/strands/base/model/load.ts +102 -0
- agentcore/assets/typescript/http/strands/base/package.json +38 -0
- agentcore/assets/typescript/http/strands/base/tsconfig.json +19 -0
- agentcore/assets/typescript/http/strands/capabilities/memory/memory.ts +52 -0
- agentcore/assets/typescript/http/vercelai/base/README.md +42 -0
- agentcore/assets/typescript/http/vercelai/base/gitignore.template +22 -0
- agentcore/assets/typescript/http/vercelai/base/main.ts +70 -0
- agentcore/assets/typescript/http/vercelai/base/model/load.ts +121 -0
- agentcore/assets/typescript/http/vercelai/base/package.json +35 -0
- agentcore/assets/typescript/http/vercelai/base/tsconfig.json +19 -0
- agentcore/aws/__init__.py +263 -0
- agentcore/aws/_aws_errors.py +72 -0
- agentcore/aws/_http.py +176 -0
- agentcore/aws/_util.py +37 -0
- agentcore/aws/account.py +165 -0
- agentcore/aws/agentcore.py +971 -0
- agentcore/aws/agentcore_ab_tests.py +230 -0
- agentcore/aws/agentcore_batch_evaluation.py +227 -0
- agentcore/aws/agentcore_config_bundles.py +220 -0
- agentcore/aws/agentcore_control.py +994 -0
- agentcore/aws/agentcore_datasets.py +222 -0
- agentcore/aws/agentcore_harness.py +330 -0
- agentcore/aws/agentcore_payments.py +430 -0
- agentcore/aws/agentcore_recommendation.py +140 -0
- agentcore/aws/agui_parser.py +131 -0
- agentcore/aws/agui_types.py +342 -0
- agentcore/aws/api_client.py +87 -0
- agentcore/aws/arn.py +18 -0
- agentcore/aws/aws_context.py +23 -0
- agentcore/aws/bedrock.py +44 -0
- agentcore/aws/bedrock_agent.py +129 -0
- agentcore/aws/bedrock_import.py +252 -0
- agentcore/aws/bedrock_import_types.py +111 -0
- agentcore/aws/cloudwatch.py +136 -0
- agentcore/aws/connect_shell.py +266 -0
- agentcore/aws/iam.py +41 -0
- agentcore/aws/partition.py +58 -0
- agentcore/aws/policy_generation.py +116 -0
- agentcore/aws/region.py +54 -0
- agentcore/aws/retry.py +27 -0
- agentcore/aws/shell_framer.py +136 -0
- agentcore/aws/stage_endpoint.py +39 -0
- agentcore/aws/target_region.py +54 -0
- agentcore/aws/transaction_search.py +97 -0
- agentcore/cdk/__init__.py +10 -0
- agentcore/cdk/constants.py +13 -0
- agentcore/cdk/local_cdk_project.py +48 -0
- agentcore/cdk/toolkit.py +706 -0
- agentcore/cli/__init__.py +0 -0
- agentcore/cli/commands/__init__.py +0 -0
- agentcore/cli/commands/_jobs_common.py +39 -0
- agentcore/cli/commands/_run_wizards.py +639 -0
- agentcore/cli/commands/add/__init__.py +37 -0
- agentcore/cli/commands/add/_commander.py +52 -0
- agentcore/cli/commands/add/_common.py +47 -0
- agentcore/cli/commands/add/agent_wizard.py +528 -0
- agentcore/cli/commands/add/auth_options.py +154 -0
- agentcore/cli/commands/add/skill_action.py +105 -0
- agentcore/cli/commands/add/skill_command.py +87 -0
- agentcore/cli/commands/add/tool_action.py +160 -0
- agentcore/cli/commands/add/tool_command.py +117 -0
- agentcore/cli/commands/add/validate.py +333 -0
- agentcore/cli/commands/capacity_provider/__init__.py +86 -0
- agentcore/cli/commands/capacity_provider/action.py +114 -0
- agentcore/cli/commands/capacity_provider/constants.py +22 -0
- agentcore/cli/commands/config.py +91 -0
- agentcore/cli/commands/config_bundle.py +251 -0
- agentcore/cli/commands/create/__init__.py +643 -0
- agentcore/cli/commands/create/action.py +406 -0
- agentcore/cli/commands/create/dependencies.py +91 -0
- agentcore/cli/commands/create/harness_validate.py +82 -0
- agentcore/cli/commands/create/validate.py +195 -0
- agentcore/cli/commands/create/wizard.py +127 -0
- agentcore/cli/commands/dataset.py +119 -0
- agentcore/cli/commands/deploy/__init__.py +31 -0
- agentcore/cli/commands/deploy/_guards.py +25 -0
- agentcore/cli/commands/deploy/actions.py +840 -0
- agentcore/cli/commands/deploy/command.py +349 -0
- agentcore/cli/commands/deploy/progress.py +115 -0
- agentcore/cli/commands/deploy/types.py +68 -0
- agentcore/cli/commands/deploy/utils.py +43 -0
- agentcore/cli/commands/deploy/validate.py +21 -0
- agentcore/cli/commands/dev/__init__.py +5 -0
- agentcore/cli/commands/dev/_deps.py +50 -0
- agentcore/cli/commands/dev/browser_mode.py +270 -0
- agentcore/cli/commands/dev/command.py +450 -0
- agentcore/cli/commands/dev/terminal_mode.py +379 -0
- agentcore/cli/commands/exec/__init__.py +29 -0
- agentcore/cli/commands/exec/action.py +442 -0
- agentcore/cli/commands/exec/command.py +206 -0
- agentcore/cli/commands/exec/types.py +35 -0
- agentcore/cli/commands/export/__init__.py +114 -0
- agentcore/cli/commands/export/constants.py +21 -0
- agentcore/cli/commands/export/fetch_harness_spec.py +234 -0
- agentcore/cli/commands/export/harness_action.py +385 -0
- agentcore/cli/commands/export/harness_mapper.py +868 -0
- agentcore/cli/commands/export/harness_resolver.py +95 -0
- agentcore/cli/commands/export/types.py +90 -0
- agentcore/cli/commands/export/wizard.py +97 -0
- agentcore/cli/commands/feedback/__init__.py +69 -0
- agentcore/cli/commands/feedback/action.py +30 -0
- agentcore/cli/commands/feedback/consent_prompt.py +35 -0
- agentcore/cli/commands/feedback/wizard.py +49 -0
- agentcore/cli/commands/fetch/__init__.py +69 -0
- agentcore/cli/commands/fetch/action.py +62 -0
- agentcore/cli/commands/help.py +65 -0
- agentcore/cli/commands/import_/__init__.py +167 -0
- agentcore/cli/commands/import_/_js.py +72 -0
- agentcore/cli/commands/import_/actions.py +457 -0
- agentcore/cli/commands/import_/constants.py +45 -0
- agentcore/cli/commands/import_/import_evaluator.py +140 -0
- agentcore/cli/commands/import_/import_gateway.py +520 -0
- agentcore/cli/commands/import_/import_memory.py +128 -0
- agentcore/cli/commands/import_/import_online_eval.py +165 -0
- agentcore/cli/commands/import_/import_pipeline.py +145 -0
- agentcore/cli/commands/import_/import_runtime.py +214 -0
- agentcore/cli/commands/import_/import_utils.py +410 -0
- agentcore/cli/commands/import_/phase1_update.py +110 -0
- agentcore/cli/commands/import_/phase2_import.py +206 -0
- agentcore/cli/commands/import_/resource_import.py +228 -0
- agentcore/cli/commands/import_/template_utils.py +148 -0
- agentcore/cli/commands/import_/types.py +150 -0
- agentcore/cli/commands/import_/yaml_parser.py +265 -0
- agentcore/cli/commands/init.py +196 -0
- agentcore/cli/commands/invoke/__init__.py +32 -0
- agentcore/cli/commands/invoke/_deps.py +73 -0
- agentcore/cli/commands/invoke/action.py +840 -0
- agentcore/cli/commands/invoke/command.py +490 -0
- agentcore/cli/commands/invoke/constants.py +40 -0
- agentcore/cli/commands/invoke/guards.py +23 -0
- agentcore/cli/commands/invoke/interactive.py +604 -0
- agentcore/cli/commands/invoke/resolve.py +149 -0
- agentcore/cli/commands/invoke/resolve_prompt.py +60 -0
- agentcore/cli/commands/invoke/types.py +61 -0
- agentcore/cli/commands/invoke/validate.py +33 -0
- agentcore/cli/commands/job_actions.py +239 -0
- agentcore/cli/commands/job_history.py +380 -0
- agentcore/cli/commands/logs/__init__.py +53 -0
- agentcore/cli/commands/logs/action.py +159 -0
- agentcore/cli/commands/logs/filter_pattern.py +17 -0
- agentcore/cli/commands/logs/guards.py +51 -0
- agentcore/cli/commands/logs_evals.py +42 -0
- agentcore/cli/commands/package.py +118 -0
- agentcore/cli/commands/remove/__init__.py +172 -0
- agentcore/cli/commands/remove/skill_command.py +131 -0
- agentcore/cli/commands/remove/tool_command.py +59 -0
- agentcore/cli/commands/run.py +808 -0
- agentcore/cli/commands/run_ingest.py +97 -0
- agentcore/cli/commands/shared/__init__.py +0 -0
- agentcore/cli/commands/shared/arn_utils.py +9 -0
- agentcore/cli/commands/shared/filesystem_utils.py +421 -0
- agentcore/cli/commands/shared/header_utils.py +87 -0
- agentcore/cli/commands/shared/indexed_key_parser.py +76 -0
- agentcore/cli/commands/shared/lifecycle_utils.py +72 -0
- agentcore/cli/commands/shared/region_utils.py +20 -0
- agentcore/cli/commands/shared/vpc_utils.py +99 -0
- agentcore/cli/commands/status/__init__.py +30 -0
- agentcore/cli/commands/status/_guards.py +25 -0
- agentcore/cli/commands/status/action.py +741 -0
- agentcore/cli/commands/status/command.py +321 -0
- agentcore/cli/commands/status/constants.py +36 -0
- agentcore/cli/commands/status/format_knowledge_base.py +111 -0
- agentcore/cli/commands/telemetry.py +79 -0
- agentcore/cli/commands/traces/__init__.py +155 -0
- agentcore/cli/commands/traces/action.py +123 -0
- agentcore/cli/commands/update/__init__.py +63 -0
- agentcore/cli/commands/update/action.py +164 -0
- agentcore/cli/commands/validate.py +165 -0
- agentcore/cli/constants.py +96 -0
- agentcore/cli/errors.py +118 -0
- agentcore/cli/external_requirements/__init__.py +67 -0
- agentcore/cli/external_requirements/checks.py +280 -0
- agentcore/cli/external_requirements/detect.py +55 -0
- agentcore/cli/external_requirements/versions.py +57 -0
- agentcore/cli/groups.py +23 -0
- agentcore/cli/interactive.py +85 -0
- agentcore/cli/main.py +137 -0
- agentcore/cli/naming.py +11 -0
- agentcore/cli/notices.py +42 -0
- agentcore/cli/project.py +34 -0
- agentcore/cli/run_command.py +27 -0
- agentcore/cli/tree.py +135 -0
- agentcore/cli/update_notifier.py +123 -0
- agentcore/cli/variadic.py +50 -0
- agentcore/cloudformation/__init__.py +84 -0
- agentcore/cloudformation/bootstrap.py +64 -0
- agentcore/cloudformation/logical_ids.py +37 -0
- agentcore/cloudformation/outputs.py +566 -0
- agentcore/cloudformation/stack_discovery.py +75 -0
- agentcore/cloudformation/stack_events.py +107 -0
- agentcore/cloudformation/stack_status.py +98 -0
- agentcore/cloudformation/types.py +44 -0
- agentcore/lib/__init__.py +68 -0
- agentcore/lib/constants.py +77 -0
- agentcore/lib/dependency_management/__init__.py +23 -0
- agentcore/lib/dependency_management/messages.py +92 -0
- agentcore/lib/dependency_management/plan.py +98 -0
- agentcore/lib/dependency_management/semver.py +137 -0
- agentcore/lib/dependency_management/sync.py +139 -0
- agentcore/lib/dependency_management/types.py +56 -0
- agentcore/lib/errors/__init__.py +5 -0
- agentcore/lib/errors/types.py +352 -0
- agentcore/lib/errors/validation.py +121 -0
- agentcore/lib/packaging/__init__.py +81 -0
- agentcore/lib/packaging/build_args.py +23 -0
- agentcore/lib/packaging/build_context.py +26 -0
- agentcore/lib/packaging/build_context_dockerignore.py +45 -0
- agentcore/lib/packaging/container.py +95 -0
- agentcore/lib/packaging/helpers.py +289 -0
- agentcore/lib/packaging/node.py +153 -0
- agentcore/lib/packaging/python.py +135 -0
- agentcore/lib/packaging/types.py +69 -0
- agentcore/lib/packaging/uv.py +45 -0
- agentcore/lib/result.py +104 -0
- agentcore/lib/schemas/__init__.py +1 -0
- agentcore/lib/schemas/io/__init__.py +27 -0
- agentcore/lib/schemas/io/config_io.py +458 -0
- agentcore/lib/schemas/io/global_config.py +239 -0
- agentcore/lib/schemas/io/path_resolver.py +132 -0
- agentcore/lib/secrets/__init__.py +18 -0
- agentcore/lib/secrets/cipher.py +70 -0
- agentcore/lib/secrets/key_provider.py +163 -0
- agentcore/lib/secrets/sensitive_keys.py +55 -0
- agentcore/lib/time_constants.py +4 -0
- agentcore/lib/utils/__init__.py +47 -0
- agentcore/lib/utils/aws_account.py +15 -0
- agentcore/lib/utils/credentials.py +68 -0
- agentcore/lib/utils/dotenv.py +32 -0
- agentcore/lib/utils/env.py +105 -0
- agentcore/lib/utils/json_format.py +29 -0
- agentcore/lib/utils/json_rpc.py +22 -0
- agentcore/lib/utils/platform.py +33 -0
- agentcore/lib/utils/polling.py +86 -0
- agentcore/lib/utils/subprocess.py +135 -0
- agentcore/lib/utils/time_parser.py +48 -0
- agentcore/lib/utils/validation.py +106 -0
- agentcore/logging/__init__.py +10 -0
- agentcore/logging/_common.py +77 -0
- agentcore/logging/cdk_io_host.py +36 -0
- agentcore/logging/create_logger.py +107 -0
- agentcore/logging/dev_logger.py +63 -0
- agentcore/logging/exec_logger.py +159 -0
- agentcore/logging/invoke_logger.py +154 -0
- agentcore/logging/remove_logger.py +95 -0
- agentcore/operations/__init__.py +0 -0
- agentcore/operations/agent/__init__.py +0 -0
- agentcore/operations/agent/config_bundle_defaults.py +31 -0
- agentcore/operations/agent/generate/__init__.py +28 -0
- agentcore/operations/agent/generate/schema_mapper.py +319 -0
- agentcore/operations/agent/generate/types.py +172 -0
- agentcore/operations/agent/generate/write_agent_to_project.py +67 -0
- agentcore/operations/agent/import_/__init__.py +31 -0
- agentcore/operations/agent/import_/base_translator.py +449 -0
- agentcore/operations/agent/import_/constants.py +23 -0
- agentcore/operations/agent/import_/execute.py +127 -0
- agentcore/operations/agent/import_/langgraph_translator.py +294 -0
- agentcore/operations/agent/import_/pyproject_generator.py +73 -0
- agentcore/operations/agent/import_/strands_translator.py +289 -0
- agentcore/operations/config_bundle/__init__.py +1 -0
- agentcore/operations/config_bundle/bundle_name_variants.py +9 -0
- agentcore/operations/config_bundle/diff_versions.py +52 -0
- agentcore/operations/config_bundle/resolve_bundle.py +65 -0
- agentcore/operations/connectors/__init__.py +3 -0
- agentcore/operations/connectors/translators.py +63 -0
- agentcore/operations/dataset/__init__.py +21 -0
- agentcore/operations/dataset/delete.py +7 -0
- agentcore/operations/dataset/publish.py +16 -0
- agentcore/operations/dataset/pull.py +21 -0
- agentcore/operations/dataset/push.py +201 -0
- agentcore/operations/dataset/resolve_dataset.py +65 -0
- agentcore/operations/dataset/status.py +18 -0
- agentcore/operations/dataset/wait.py +25 -0
- agentcore/operations/deploy/__init__.py +152 -0
- agentcore/operations/deploy/backfill_vpc_id.py +90 -0
- agentcore/operations/deploy/change_detection.py +84 -0
- agentcore/operations/deploy/constants.py +58 -0
- agentcore/operations/deploy/dependency_sync.py +105 -0
- agentcore/operations/deploy/ensure_target.py +30 -0
- agentcore/operations/deploy/gateway_status.py +44 -0
- agentcore/operations/deploy/managed_memory_notice.py +36 -0
- agentcore/operations/deploy/payment_connector_authorization.py +106 -0
- agentcore/operations/deploy/post_deploy_datasets.py +96 -0
- agentcore/operations/deploy/post_deploy_knowledge_bases.py +104 -0
- agentcore/operations/deploy/post_deploy_observability.py +28 -0
- agentcore/operations/deploy/post_deploy_online_evals.py +60 -0
- agentcore/operations/deploy/pre_deploy_identity.py +505 -0
- agentcore/operations/deploy/preflight.py +385 -0
- agentcore/operations/deploy/region_override.py +45 -0
- agentcore/operations/deploy/teardown.py +153 -0
- agentcore/operations/dev/__init__.py +61 -0
- agentcore/operations/dev/_http.py +79 -0
- agentcore/operations/dev/_server.py +165 -0
- agentcore/operations/dev/codezip_dev_server.py +151 -0
- agentcore/operations/dev/config.py +128 -0
- agentcore/operations/dev/constants.py +9 -0
- agentcore/operations/dev/container_dev_server.py +237 -0
- agentcore/operations/dev/container_runtime.py +37 -0
- agentcore/operations/dev/dev_server.py +244 -0
- agentcore/operations/dev/gateway_env.py +25 -0
- agentcore/operations/dev/invoke.py +214 -0
- agentcore/operations/dev/invoke_a2a.py +204 -0
- agentcore/operations/dev/invoke_agui.py +88 -0
- agentcore/operations/dev/invoke_mcp.py +145 -0
- agentcore/operations/dev/invoke_types.py +30 -0
- agentcore/operations/dev/load_dev_env.py +26 -0
- agentcore/operations/dev/memory_env.py +19 -0
- agentcore/operations/dev/otel/__init__.py +5 -0
- agentcore/operations/dev/otel/collector.py +234 -0
- agentcore/operations/dev/otel/transforms.py +331 -0
- agentcore/operations/dev/payment_env.py +50 -0
- agentcore/operations/dev/server.py +28 -0
- agentcore/operations/dev/sse_transform.py +30 -0
- agentcore/operations/dev/utils.py +152 -0
- agentcore/operations/dev/web_ui/__init__.py +31 -0
- agentcore/operations/dev/web_ui/constants.py +25 -0
- agentcore/operations/dev/web_ui/handlers/__init__.py +36 -0
- agentcore/operations/dev/web_ui/handlers/_common.py +36 -0
- agentcore/operations/dev/web_ui/handlers/_deployed.py +37 -0
- agentcore/operations/dev/web_ui/handlers/a2a_proxy.py +37 -0
- agentcore/operations/dev/web_ui/handlers/cloudwatch_traces.py +71 -0
- agentcore/operations/dev/web_ui/handlers/harness_invocation.py +89 -0
- agentcore/operations/dev/web_ui/handlers/harness_utils.py +95 -0
- agentcore/operations/dev/web_ui/handlers/invocations.py +327 -0
- agentcore/operations/dev/web_ui/handlers/mcp_proxy.py +119 -0
- agentcore/operations/dev/web_ui/handlers/memory.py +84 -0
- agentcore/operations/dev/web_ui/handlers/resources.py +351 -0
- agentcore/operations/dev/web_ui/handlers/start.py +182 -0
- agentcore/operations/dev/web_ui/handlers/status.py +25 -0
- agentcore/operations/dev/web_ui/handlers/traces.py +50 -0
- agentcore/operations/dev/web_ui/run_web_ui.py +60 -0
- agentcore/operations/dev/web_ui/web_server.py +297 -0
- agentcore/operations/eval/__init__.py +8 -0
- agentcore/operations/eval/list_eval_runs.py +18 -0
- agentcore/operations/eval/logs_eval.py +119 -0
- agentcore/operations/eval/pause_resume.py +90 -0
- agentcore/operations/eval/run_eval.py +354 -0
- agentcore/operations/eval/shared/__init__.py +0 -0
- agentcore/operations/eval/shared/dataset_loader.py +68 -0
- agentcore/operations/eval/shared/dataset_session_provider.py +122 -0
- agentcore/operations/eval/shared/evaluator_runner.py +89 -0
- agentcore/operations/eval/shared/scenario_executor.py +71 -0
- agentcore/operations/eval/shared/span_collector.py +255 -0
- agentcore/operations/eval/storage.py +67 -0
- agentcore/operations/feedback/__init__.py +21 -0
- agentcore/operations/feedback/aperture_client.py +98 -0
- agentcore/operations/feedback/build_payload.py +97 -0
- agentcore/operations/feedback/constants.py +26 -0
- agentcore/operations/feedback/submit_feedback.py +150 -0
- agentcore/operations/fetch_access/__init__.py +36 -0
- agentcore/operations/fetch_access/_target.py +17 -0
- agentcore/operations/fetch_access/fetch_gateway_token.py +75 -0
- agentcore/operations/fetch_access/fetch_harness_token.py +72 -0
- agentcore/operations/fetch_access/fetch_runtime_token.py +76 -0
- agentcore/operations/fetch_access/list_agents.py +18 -0
- agentcore/operations/fetch_access/list_gateways.py +26 -0
- agentcore/operations/fetch_access/list_harnesses.py +23 -0
- agentcore/operations/fetch_access/oauth_token.py +162 -0
- agentcore/operations/fetch_access/types.py +34 -0
- agentcore/operations/harness/__init__.py +1 -0
- agentcore/operations/harness/orphan.py +84 -0
- agentcore/operations/harness/skill_utils.py +56 -0
- agentcore/operations/identity/__init__.py +33 -0
- agentcore/operations/identity/api_key_credential_provider.py +68 -0
- agentcore/operations/identity/oauth2_credential_provider.py +95 -0
- agentcore/operations/ingest/__init__.py +184 -0
- agentcore/operations/init/__init__.py +3 -0
- agentcore/operations/init/files.py +59 -0
- agentcore/operations/insights/__init__.py +21 -0
- agentcore/operations/insights/insights_storage.py +67 -0
- agentcore/operations/insights/run_insights.py +148 -0
- agentcore/operations/invoke/__init__.py +5 -0
- agentcore/operations/invoke/resolve_agent_context.py +85 -0
- agentcore/operations/jobs/__init__.py +38 -0
- agentcore/operations/jobs/ab_test/__init__.py +0 -0
- agentcore/operations/jobs/ab_test/build_options.py +126 -0
- agentcore/operations/jobs/ab_test/format.py +121 -0
- agentcore/operations/jobs/ab_test/handler.py +412 -0
- agentcore/operations/jobs/ab_test/promote.py +142 -0
- agentcore/operations/jobs/ab_test/resolve.py +221 -0
- agentcore/operations/jobs/batch_evaluation/__init__.py +0 -0
- agentcore/operations/jobs/batch_evaluation/build_source.py +68 -0
- agentcore/operations/jobs/batch_evaluation/dataset_phase1.py +95 -0
- agentcore/operations/jobs/batch_evaluation/format.py +58 -0
- agentcore/operations/jobs/batch_evaluation/handler.py +203 -0
- agentcore/operations/jobs/insights/__init__.py +0 -0
- agentcore/operations/jobs/insights/format.py +65 -0
- agentcore/operations/jobs/insights/handler.py +178 -0
- agentcore/operations/jobs/recommendation/__init__.py +0 -0
- agentcore/operations/jobs/recommendation/apply_to_bundle.py +76 -0
- agentcore/operations/jobs/recommendation/build_config.py +271 -0
- agentcore/operations/jobs/recommendation/fetch_session_spans.py +93 -0
- agentcore/operations/jobs/recommendation/format.py +77 -0
- agentcore/operations/jobs/recommendation/handler.py +331 -0
- agentcore/operations/jobs/shared/__init__.py +0 -0
- agentcore/operations/jobs/shared/constants.py +85 -0
- agentcore/operations/jobs/shared/engine.py +187 -0
- agentcore/operations/jobs/shared/format.py +104 -0
- agentcore/operations/jobs/shared/region.py +34 -0
- agentcore/operations/jobs/shared/resolve_agent_state.py +30 -0
- agentcore/operations/jobs/shared/storage.py +117 -0
- agentcore/operations/jobs/shared/wait.py +30 -0
- agentcore/operations/knowledge_base/__init__.py +33 -0
- agentcore/operations/knowledge_base/connector_config.py +105 -0
- agentcore/operations/knowledge_base/hydrate_data_sources.py +59 -0
- agentcore/operations/mcp/__init__.py +4 -0
- agentcore/operations/memory/__init__.py +13 -0
- agentcore/operations/memory/_records.py +72 -0
- agentcore/operations/memory/list_memory_records.py +45 -0
- agentcore/operations/memory/retrieve_memory_records.py +52 -0
- agentcore/operations/node/__init__.py +15 -0
- agentcore/operations/node/setup.py +36 -0
- agentcore/operations/python/__init__.py +17 -0
- agentcore/operations/python/setup.py +47 -0
- agentcore/operations/resolve_agent.py +159 -0
- agentcore/operations/session/__init__.py +86 -0
- agentcore/operations/traces/__init__.py +29 -0
- agentcore/operations/traces/get_trace.py +202 -0
- agentcore/operations/traces/insights_query.py +74 -0
- agentcore/operations/traces/list_traces.py +46 -0
- agentcore/operations/traces/trace_url.py +25 -0
- agentcore/operations/traces/types.py +55 -0
- agentcore/primitives/__init__.py +0 -0
- agentcore/primitives/_gateway_target_wizard.py +293 -0
- agentcore/primitives/_gateway_validation.py +442 -0
- agentcore/primitives/_harness_cli.py +557 -0
- agentcore/primitives/_harness_validation.py +163 -0
- agentcore/primitives/_harness_wizard.py +726 -0
- agentcore/primitives/_knowledge_base_wizard.py +259 -0
- agentcore/primitives/_payment_wizard.py +331 -0
- agentcore/primitives/_policy_form.py +160 -0
- agentcore/primitives/agent.py +817 -0
- agentcore/primitives/auth_utils.py +77 -0
- agentcore/primitives/base.py +178 -0
- agentcore/primitives/capacity_provider.py +501 -0
- agentcore/primitives/config_bundle.py +329 -0
- agentcore/primitives/credential.py +387 -0
- agentcore/primitives/credential_utils.py +45 -0
- agentcore/primitives/dataset.py +211 -0
- agentcore/primitives/deployed_gateways.py +34 -0
- agentcore/primitives/evaluator.py +909 -0
- agentcore/primitives/gateway.py +496 -0
- agentcore/primitives/gateway_target.py +988 -0
- agentcore/primitives/harness.py +706 -0
- agentcore/primitives/knowledge_base.py +477 -0
- agentcore/primitives/memory.py +387 -0
- agentcore/primitives/online_eval_config.py +365 -0
- agentcore/primitives/online_insights.py +275 -0
- agentcore/primitives/payment_connector.py +427 -0
- agentcore/primitives/payment_eligible.py +20 -0
- agentcore/primitives/payment_manager.py +605 -0
- agentcore/primitives/payment_validation.py +68 -0
- agentcore/primitives/policy.py +622 -0
- agentcore/primitives/policy_engine.py +358 -0
- agentcore/primitives/registry.py +56 -0
- agentcore/primitives/runtime_endpoint.py +361 -0
- agentcore/primitives/secret_flag_warning.py +17 -0
- agentcore/schema/__init__.py +14 -0
- agentcore/schema/_zod.py +395 -0
- agentcore/schema/constants.py +306 -0
- agentcore/schema/schemas/__init__.py +40 -0
- agentcore/schema/schemas/agent_env.py +545 -0
- agentcore/schema/schemas/agentcore_project.py +530 -0
- agentcore/schema/schemas/auth.py +286 -0
- agentcore/schema/schemas/aws_targets.py +72 -0
- agentcore/schema/schemas/connections.py +187 -0
- agentcore/schema/schemas/deployed_state.py +322 -0
- agentcore/schema/schemas/mcp.py +650 -0
- agentcore/schema/schemas/mcp_defs.py +54 -0
- agentcore/schema/schemas/primitives/__init__.py +52 -0
- agentcore/schema/schemas/primitives/ab_test.py +162 -0
- agentcore/schema/schemas/primitives/capacity_provider.py +214 -0
- agentcore/schema/schemas/primitives/config_bundle.py +48 -0
- agentcore/schema/schemas/primitives/dataset.py +55 -0
- agentcore/schema/schemas/primitives/evaluator.py +171 -0
- agentcore/schema/schemas/primitives/harness.py +710 -0
- agentcore/schema/schemas/primitives/knowledge_base.py +90 -0
- agentcore/schema/schemas/primitives/memory.py +113 -0
- agentcore/schema/schemas/primitives/online_eval_config.py +77 -0
- agentcore/schema/schemas/primitives/payment.py +114 -0
- agentcore/schema/schemas/primitives/policy.py +83 -0
- agentcore/schema/schemas/primitives/tags.py +50 -0
- agentcore/schema/schemas/zod_util.py +5 -0
- agentcore/schema/types/__init__.py +3 -0
- agentcore/schema/types/path.py +16 -0
- agentcore/templates/__init__.py +115 -0
- agentcore/templates/_handlebars.py +782 -0
- agentcore/templates/_js.py +164 -0
- agentcore/templates/base_renderer.py +107 -0
- agentcore/templates/cdk_renderer.py +129 -0
- agentcore/templates/evaluator_renderer.py +39 -0
- agentcore/templates/gateway_target_renderer.py +69 -0
- agentcore/templates/llm_context/README.md +16 -0
- agentcore/templates/llm_context/agentcore.ts +685 -0
- agentcore/templates/llm_context/aws-targets.ts +51 -0
- agentcore/templates/profiles.py +151 -0
- agentcore/templates/render.py +92 -0
- agentcore/templates/renderers.py +83 -0
- agentcore/templates/schema_assets.py +23 -0
- agentcore/templates/template_root.py +28 -0
- agentcore/templates/types.py +192 -0
- agentcore_cli-0.31.1.dist-info/METADATA +84 -0
- agentcore_cli-0.31.1.dist-info/RECORD +655 -0
- agentcore_cli-0.31.1.dist-info/WHEEL +4 -0
- agentcore_cli-0.31.1.dist-info/entry_points.txt +2 -0
- agentcore_cli-0.31.1.dist-info/licenses/LICENSE +175 -0
- agentcore_cli-0.31.1.dist-info/licenses/NOTICE +88 -0
|
@@ -0,0 +1,622 @@
|
|
|
1
|
+
"""Cedar policy add/remove (port of src/cli/primitives/PolicyPrimitive.ts).
|
|
2
|
+
|
|
3
|
+
Policies come from an inline statement, a file, natural-language generation (deployed engine
|
|
4
|
+
required), or the guardrail form (``--form-*``), which synthesizes Cedar locally.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
from dataclasses import dataclass
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
import typer
|
|
12
|
+
|
|
13
|
+
from agentcore.aws import detect_region, policy_generation
|
|
14
|
+
from agentcore.cli import interactive
|
|
15
|
+
from agentcore.cli.commands.add._common import first_issue
|
|
16
|
+
from agentcore.cli.errors import get_error_message
|
|
17
|
+
from agentcore.cli.naming import generate_unique_name
|
|
18
|
+
from agentcore.cli.run_command import run_cli_command
|
|
19
|
+
from agentcore.lib import ResourceNotFoundError, ValidationError, find_config_root, serialize_result
|
|
20
|
+
from agentcore.lib.errors.types import to_error
|
|
21
|
+
from agentcore.lib.result import Err, Ok
|
|
22
|
+
from agentcore.lib.schemas.io.config_io import to_jsonable
|
|
23
|
+
from agentcore.primitives._policy_form import (
|
|
24
|
+
ENFORCEMENT_MODE_OPTIONS,
|
|
25
|
+
FILTERS_BY_CATEGORY,
|
|
26
|
+
GUARDRAIL_CATEGORY_OPTIONS,
|
|
27
|
+
POLICY_EFFECT_OPTIONS,
|
|
28
|
+
POLICY_SOURCE_METHOD_OPTIONS,
|
|
29
|
+
VALIDATION_MODE_OPTIONS,
|
|
30
|
+
GuardrailFormConfig,
|
|
31
|
+
authorization_phase_for_effect,
|
|
32
|
+
default_data_path_for_effect,
|
|
33
|
+
invalid_filters_for_category,
|
|
34
|
+
synthesize_cedar,
|
|
35
|
+
)
|
|
36
|
+
from agentcore.primitives.base import BasePrimitive, RemovableResource, RemovalPreview, SchemaChange, emit_json
|
|
37
|
+
from agentcore.primitives.deployed_gateways import find_deployed_gateway, first_deployed_gateway
|
|
38
|
+
from agentcore.schema import ENFORCEMENT_MODES, VALIDATION_MODES, PolicyName
|
|
39
|
+
|
|
40
|
+
_ALLOWED_CATEGORIES = ("contentFilter", "promptAttack", "sensitiveInformation")
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@dataclass
|
|
44
|
+
class AddPolicyOptions:
|
|
45
|
+
name: str
|
|
46
|
+
engine: str
|
|
47
|
+
description: str | None = None
|
|
48
|
+
statement: str | None = None
|
|
49
|
+
source: str | None = None
|
|
50
|
+
generate: str | None = None
|
|
51
|
+
gateway: str | None = None
|
|
52
|
+
validation_mode: str | None = None
|
|
53
|
+
enforcement_mode: str | None = None
|
|
54
|
+
authorization_phase: str | None = None
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def _parse_enum(value: str, allowed: tuple[str, ...]) -> str:
|
|
58
|
+
if value not in allowed:
|
|
59
|
+
expected = "|".join(f'"{v}"' for v in allowed)
|
|
60
|
+
raise ValueError(f"Invalid option: expected one of {expected}")
|
|
61
|
+
return value
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _split_key(key: str) -> tuple[str | None, str]:
|
|
65
|
+
if "/" in key:
|
|
66
|
+
engine, _, policy = key.partition("/")
|
|
67
|
+
return engine, policy
|
|
68
|
+
return None, key
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class PolicyPrimitive(BasePrimitive):
|
|
72
|
+
kind = "policy"
|
|
73
|
+
label = "Policy"
|
|
74
|
+
|
|
75
|
+
def _project(self) -> dict[str, Any]:
|
|
76
|
+
return to_jsonable(self.read_project_spec())
|
|
77
|
+
|
|
78
|
+
# --- add ----------------------------------------------------------------------------
|
|
79
|
+
|
|
80
|
+
def add(self, options: AddPolicyOptions) -> Ok[dict[str, Any]] | Err[Exception]:
|
|
81
|
+
try:
|
|
82
|
+
if len([f for f in (options.statement, options.source, options.generate) if f]) > 1:
|
|
83
|
+
return Err(ValidationError("Only one of --statement, --source, or --generate can be provided."))
|
|
84
|
+
|
|
85
|
+
project = self._project()
|
|
86
|
+
engine = next((e for e in project["policyEngines"] if e["name"] == options.engine), None)
|
|
87
|
+
if engine is None:
|
|
88
|
+
return Err(ResourceNotFoundError(f'Policy engine "{options.engine}" not found.'))
|
|
89
|
+
|
|
90
|
+
self.check_duplicate([RemovableResource(p["name"]) for p in engine["policies"]], options.name, "Policy")
|
|
91
|
+
|
|
92
|
+
statement = options.statement or ""
|
|
93
|
+
|
|
94
|
+
if options.source and not statement:
|
|
95
|
+
if not os.path.exists(options.source):
|
|
96
|
+
return Err(ResourceNotFoundError(f"Source file not found: {options.source}"))
|
|
97
|
+
with open(options.source, encoding="utf-8") as fh:
|
|
98
|
+
statement = fh.read().strip()
|
|
99
|
+
if not statement:
|
|
100
|
+
return Err(ValidationError(f"Source file is empty: {options.source}"))
|
|
101
|
+
|
|
102
|
+
if options.generate and not statement:
|
|
103
|
+
state = self.config_io.read_deployed_state()
|
|
104
|
+
engine_id: str | None = None
|
|
105
|
+
for target in (state.targets or {}).values():
|
|
106
|
+
engines = (target.resources.policy_engines if target.resources else None) or {}
|
|
107
|
+
if engine_id is None and options.engine in engines:
|
|
108
|
+
engine_id = engines[options.engine].policy_engine_id
|
|
109
|
+
|
|
110
|
+
gateway = (
|
|
111
|
+
find_deployed_gateway(state, options.gateway) if options.gateway else first_deployed_gateway(state)
|
|
112
|
+
)
|
|
113
|
+
gateway_arn = gateway.gateway_arn if gateway is not None else None
|
|
114
|
+
|
|
115
|
+
if not engine_id:
|
|
116
|
+
return Err(
|
|
117
|
+
ValidationError(
|
|
118
|
+
f'Policy engine "{options.engine}" is not deployed. Run `agentcore deploy` first.'
|
|
119
|
+
)
|
|
120
|
+
)
|
|
121
|
+
if options.gateway and not gateway_arn:
|
|
122
|
+
return Err(ResourceNotFoundError(f'Gateway "{options.gateway}" not found in deployed state.'))
|
|
123
|
+
if not gateway_arn:
|
|
124
|
+
return Err(
|
|
125
|
+
ResourceNotFoundError(
|
|
126
|
+
"No deployed gateway found. Policy generation requires a deployed gateway. "
|
|
127
|
+
"Use --gateway <name> to specify one."
|
|
128
|
+
)
|
|
129
|
+
)
|
|
130
|
+
statement = self._generate(engine_id, options.generate, gateway_arn)
|
|
131
|
+
|
|
132
|
+
if not statement:
|
|
133
|
+
return Err(ValidationError("Either --statement, --source, or --generate is required."))
|
|
134
|
+
|
|
135
|
+
policy: dict[str, Any] = {"name": options.name}
|
|
136
|
+
if options.description:
|
|
137
|
+
policy["description"] = options.description
|
|
138
|
+
policy["statement"] = statement
|
|
139
|
+
if options.source:
|
|
140
|
+
policy["sourceFile"] = options.source
|
|
141
|
+
policy["validationMode"] = options.validation_mode or "FAIL_ON_ANY_FINDINGS"
|
|
142
|
+
policy["enforcementMode"] = options.enforcement_mode or "ACTIVE"
|
|
143
|
+
if options.authorization_phase:
|
|
144
|
+
policy["authorizationPhase"] = options.authorization_phase
|
|
145
|
+
|
|
146
|
+
engine["policies"].append(policy)
|
|
147
|
+
self.write_project_spec(project)
|
|
148
|
+
return Ok({"policyName": options.name, "engineName": options.engine})
|
|
149
|
+
except Exception as exc: # noqa: BLE001
|
|
150
|
+
return Err(to_error(exc))
|
|
151
|
+
|
|
152
|
+
@staticmethod
|
|
153
|
+
def _generate(engine_id: str, description: str, gateway_arn: str) -> str:
|
|
154
|
+
region = detect_region().region
|
|
155
|
+
start = policy_generation.start_policy_generation(
|
|
156
|
+
policy_engine_id=engine_id, description=description, region=region, resource_arn=gateway_arn
|
|
157
|
+
)
|
|
158
|
+
result = policy_generation.get_policy_generation(
|
|
159
|
+
generation_id=start["generationId"], policy_engine_id=engine_id, region=region
|
|
160
|
+
)
|
|
161
|
+
return result["statement"]
|
|
162
|
+
|
|
163
|
+
# --- remove -------------------------------------------------------------------------
|
|
164
|
+
|
|
165
|
+
def remove(self, name: str, engine_name: str | None = None) -> Ok[None] | Err[Exception]:
|
|
166
|
+
"""Remove by composite key ``engine/policy`` or by policy name (+ optional engine)."""
|
|
167
|
+
try:
|
|
168
|
+
project = self._project()
|
|
169
|
+
resolved_engine, resolved_policy = engine_name, name
|
|
170
|
+
if not resolved_engine and "/" in name:
|
|
171
|
+
resolved_engine, resolved_policy = _split_key(name)
|
|
172
|
+
|
|
173
|
+
if not resolved_engine:
|
|
174
|
+
matching = [
|
|
175
|
+
e for e in project["policyEngines"] if any(p["name"] == resolved_policy for p in e["policies"])
|
|
176
|
+
]
|
|
177
|
+
if len(matching) > 1:
|
|
178
|
+
return Err(
|
|
179
|
+
ValidationError(
|
|
180
|
+
f'Policy "{resolved_policy}" exists in multiple engines: '
|
|
181
|
+
f"{', '.join(e['name'] for e in matching)}. Use --engine to specify which one."
|
|
182
|
+
)
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
for engine in project["policyEngines"]:
|
|
186
|
+
if resolved_engine and engine["name"] != resolved_engine:
|
|
187
|
+
continue
|
|
188
|
+
index = next((i for i, p in enumerate(engine["policies"]) if p["name"] == resolved_policy), -1)
|
|
189
|
+
if index != -1:
|
|
190
|
+
engine["policies"].pop(index)
|
|
191
|
+
self.write_project_spec(project)
|
|
192
|
+
return Ok(None)
|
|
193
|
+
|
|
194
|
+
suffix = f' in engine "{resolved_engine}"' if resolved_engine else ""
|
|
195
|
+
return Err(ResourceNotFoundError(f'Policy "{resolved_policy}" not found{suffix}.'))
|
|
196
|
+
except Exception as exc: # noqa: BLE001
|
|
197
|
+
return Err(to_error(exc))
|
|
198
|
+
|
|
199
|
+
def preview_remove(self, name: str) -> RemovalPreview:
|
|
200
|
+
project = self._project()
|
|
201
|
+
target_engine, target_policy = _split_key(name)
|
|
202
|
+
|
|
203
|
+
if not target_engine:
|
|
204
|
+
matching = [e for e in project["policyEngines"] if any(p["name"] == target_policy for p in e["policies"])]
|
|
205
|
+
if len(matching) > 1:
|
|
206
|
+
raise Exception(
|
|
207
|
+
f'Policy "{target_policy}" exists in multiple engines: '
|
|
208
|
+
f"{', '.join(e['name'] for e in matching)}. Use --engine to specify which one."
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
for engine in project["policyEngines"]:
|
|
212
|
+
if target_engine and engine["name"] != target_engine:
|
|
213
|
+
continue
|
|
214
|
+
if any(p["name"] == target_policy for p in engine["policies"]):
|
|
215
|
+
after = {
|
|
216
|
+
**project,
|
|
217
|
+
"policyEngines": [
|
|
218
|
+
e
|
|
219
|
+
if e["name"] != engine["name"]
|
|
220
|
+
else {**e, "policies": [p for p in e["policies"] if p["name"] != target_policy]}
|
|
221
|
+
for e in project["policyEngines"]
|
|
222
|
+
],
|
|
223
|
+
}
|
|
224
|
+
return RemovalPreview(
|
|
225
|
+
[f"Removing policy: {target_policy} (from engine {engine['name']})"],
|
|
226
|
+
[],
|
|
227
|
+
[SchemaChange("agentcore/agentcore.json", project, after)],
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
suffix = f' in engine "{target_engine}"' if target_engine else ""
|
|
231
|
+
raise Exception(f'Policy "{target_policy}" not found{suffix}.')
|
|
232
|
+
|
|
233
|
+
def get_removable(self) -> list[RemovableResource]:
|
|
234
|
+
try:
|
|
235
|
+
return [
|
|
236
|
+
RemovableResource(f"{e['name']}/{p['name']}", {"engineName": e["name"]})
|
|
237
|
+
for e in self._project()["policyEngines"]
|
|
238
|
+
for p in e["policies"]
|
|
239
|
+
]
|
|
240
|
+
except Exception: # noqa: BLE001
|
|
241
|
+
return []
|
|
242
|
+
|
|
243
|
+
# --- CLI ----------------------------------------------------------------------------
|
|
244
|
+
|
|
245
|
+
def register_commands(self, add_app: typer.Typer, remove_app: typer.Typer) -> None:
|
|
246
|
+
@add_app.command("policy", help="Add a policy to a policy engine")
|
|
247
|
+
def add_policy(
|
|
248
|
+
name: str | None = typer.Option(None, "--name", help="Policy name [non-interactive]"),
|
|
249
|
+
engine: str | None = typer.Option(None, "--engine", help="Policy engine name [non-interactive]"),
|
|
250
|
+
description: str | None = typer.Option(None, "--description", help="Policy description [non-interactive]"),
|
|
251
|
+
source: str | None = typer.Option(None, "--source", help="Path to a policy file [non-interactive]"),
|
|
252
|
+
statement: str | None = typer.Option(None, "--statement", help="Policy statement [non-interactive]"),
|
|
253
|
+
generate: str | None = typer.Option(
|
|
254
|
+
None,
|
|
255
|
+
"-g",
|
|
256
|
+
"--generate",
|
|
257
|
+
help="Generate policy from natural language description [non-interactive]",
|
|
258
|
+
),
|
|
259
|
+
gateway: str | None = typer.Option(
|
|
260
|
+
None, "--gateway", help="Deployed gateway name for policy generation [non-interactive]"
|
|
261
|
+
),
|
|
262
|
+
target: str | None = typer.Option(
|
|
263
|
+
None, "--target", help="Gateway target name for Cedar action scope [non-interactive]"
|
|
264
|
+
),
|
|
265
|
+
form_category: str | None = typer.Option(
|
|
266
|
+
None,
|
|
267
|
+
"--form-category",
|
|
268
|
+
help="Guardrail category: contentFilter, promptAttack, or sensitiveInformation [non-interactive]",
|
|
269
|
+
),
|
|
270
|
+
form_filters: str | None = typer.Option(
|
|
271
|
+
None, "--form-filters", help="Comma-separated filters for the chosen category [non-interactive]"
|
|
272
|
+
),
|
|
273
|
+
form_effect: str | None = typer.Option(
|
|
274
|
+
None,
|
|
275
|
+
"--form-effect",
|
|
276
|
+
help="Policy effect: forbid, permit, or suppressOutput (default: forbid) [non-interactive]",
|
|
277
|
+
),
|
|
278
|
+
form_data_path: str | None = typer.Option(
|
|
279
|
+
None,
|
|
280
|
+
"--form-data-path",
|
|
281
|
+
help="Data path to evaluate, e.g. context.input.prompt (default: context.input.prompt) "
|
|
282
|
+
"[non-interactive]",
|
|
283
|
+
),
|
|
284
|
+
validation_mode: str | None = typer.Option(
|
|
285
|
+
None,
|
|
286
|
+
"--validation-mode",
|
|
287
|
+
help="Validation mode: FAIL_ON_ANY_FINDINGS or IGNORE_ALL_FINDINGS [non-interactive]",
|
|
288
|
+
),
|
|
289
|
+
enforcement_mode: str | None = typer.Option(
|
|
290
|
+
None,
|
|
291
|
+
"--enforcement-mode",
|
|
292
|
+
help="Enforcement mode: ACTIVE (enforce decisions) or LOG_ONLY (shadow mode) (default: ACTIVE) "
|
|
293
|
+
"[non-interactive]",
|
|
294
|
+
),
|
|
295
|
+
as_json: bool = typer.Option(False, "--json", help="Output as JSON [non-interactive]"),
|
|
296
|
+
) -> None:
|
|
297
|
+
if not find_config_root():
|
|
298
|
+
typer.echo("No agentcore project found. Run `agentcore create` first.", err=True)
|
|
299
|
+
raise typer.Exit(1)
|
|
300
|
+
|
|
301
|
+
if not (name or engine or source or statement or generate or form_category or as_json):
|
|
302
|
+
try:
|
|
303
|
+
interactive.require_tty()
|
|
304
|
+
self.add_interactive()
|
|
305
|
+
except typer.Exit:
|
|
306
|
+
raise
|
|
307
|
+
except Exception as exc: # noqa: BLE001
|
|
308
|
+
typer.echo(get_error_message(exc), err=True)
|
|
309
|
+
raise typer.Exit(1) from None
|
|
310
|
+
raise typer.Exit(0)
|
|
311
|
+
|
|
312
|
+
def run() -> None:
|
|
313
|
+
if not name:
|
|
314
|
+
raise Exception("--name is required")
|
|
315
|
+
if not engine:
|
|
316
|
+
raise Exception("--engine is required")
|
|
317
|
+
if len([f for f in (statement, source, generate, form_category) if f]) > 1:
|
|
318
|
+
raise Exception("Only one of --statement, --source, --generate, or --form-* can be provided.")
|
|
319
|
+
if enforcement_mode and enforcement_mode not in ENFORCEMENT_MODES:
|
|
320
|
+
raise Exception("Invalid --enforcement-mode. Use ACTIVE or LOG_ONLY.")
|
|
321
|
+
|
|
322
|
+
options = AddPolicyOptions(
|
|
323
|
+
name=name,
|
|
324
|
+
engine=engine,
|
|
325
|
+
description=description,
|
|
326
|
+
source=source,
|
|
327
|
+
statement=statement,
|
|
328
|
+
generate=generate,
|
|
329
|
+
gateway=gateway,
|
|
330
|
+
validation_mode=_parse_enum(validation_mode, VALIDATION_MODES) if validation_mode else None,
|
|
331
|
+
enforcement_mode=enforcement_mode or None,
|
|
332
|
+
authorization_phase="INITIATE",
|
|
333
|
+
)
|
|
334
|
+
|
|
335
|
+
if form_category:
|
|
336
|
+
options.statement, options.authorization_phase = self._synthesize_from_flags(
|
|
337
|
+
form_category, form_filters, form_effect, form_data_path, gateway, target
|
|
338
|
+
)
|
|
339
|
+
|
|
340
|
+
result = self.add(options)
|
|
341
|
+
if not result.success:
|
|
342
|
+
raise result.error
|
|
343
|
+
if as_json:
|
|
344
|
+
emit_json(serialize_result(result))
|
|
345
|
+
else:
|
|
346
|
+
typer.echo(f"Added policy '{result.value['policyName']}' to engine '{result.value['engineName']}'")
|
|
347
|
+
|
|
348
|
+
run_cli_command(as_json, run)
|
|
349
|
+
|
|
350
|
+
@remove_app.command("policy", help="Remove a policy from a policy engine")
|
|
351
|
+
def remove_policy(
|
|
352
|
+
name: str | None = typer.Option(None, "--name", help="Name of policy to remove [non-interactive]"),
|
|
353
|
+
engine: str | None = typer.Option(None, "--engine", help="Policy engine name [non-interactive]"),
|
|
354
|
+
yes: bool = typer.Option(False, "-y", "--yes", help="Skip confirmation prompt [non-interactive]"),
|
|
355
|
+
as_json: bool = typer.Option(False, "--json", help="Output as JSON [non-interactive]"),
|
|
356
|
+
) -> None:
|
|
357
|
+
if (name or yes or as_json) and not name and not as_json:
|
|
358
|
+
# Upstream prints a plain message (not JSON) here when --json is absent.
|
|
359
|
+
if find_config_root():
|
|
360
|
+
typer.echo("--name is required", err=True)
|
|
361
|
+
raise typer.Exit(1)
|
|
362
|
+
from agentcore.primitives.policy_engine import PRIMITIVE as engine_primitive
|
|
363
|
+
|
|
364
|
+
key = f"{engine}/{name}" if engine and name else None
|
|
365
|
+
engine_primitive._run_remove_with_text.__func__(self, name, yes, as_json, key) # type: ignore[attr-defined]
|
|
366
|
+
|
|
367
|
+
def _synthesize_from_flags(
|
|
368
|
+
self,
|
|
369
|
+
category: str,
|
|
370
|
+
filters_raw: str | None,
|
|
371
|
+
effect_raw: str | None,
|
|
372
|
+
data_path: str | None,
|
|
373
|
+
gateway: str | None,
|
|
374
|
+
target: str | None,
|
|
375
|
+
) -> tuple[str, str]:
|
|
376
|
+
if not filters_raw:
|
|
377
|
+
raise Exception("--form-filters is required when --form-category is specified.")
|
|
378
|
+
if category not in _ALLOWED_CATEGORIES:
|
|
379
|
+
raise Exception(f"Unknown category: {category}. Allowed: {', '.join(_ALLOWED_CATEGORIES)}")
|
|
380
|
+
effect = effect_raw or "forbid"
|
|
381
|
+
if effect not in ("permit", "forbid", "suppressOutput"):
|
|
382
|
+
raise Exception("Invalid --form-effect. Use permit, forbid, or suppressOutput.")
|
|
383
|
+
filters = [s.strip() for s in filters_raw.split(",")]
|
|
384
|
+
invalid = invalid_filters_for_category(category, filters)
|
|
385
|
+
if invalid:
|
|
386
|
+
raise ValidationError(
|
|
387
|
+
f"Invalid filter(s) for category '{category}': {', '.join(invalid)}. "
|
|
388
|
+
f"Allowed: {', '.join(FILTERS_BY_CATEGORY[category])}"
|
|
389
|
+
)
|
|
390
|
+
|
|
391
|
+
gateway_arn: str | None = None
|
|
392
|
+
target_name = target
|
|
393
|
+
if gateway:
|
|
394
|
+
try:
|
|
395
|
+
state = self.config_io.read_deployed_state()
|
|
396
|
+
deployed = find_deployed_gateway(state, gateway)
|
|
397
|
+
if deployed is not None and deployed.gateway_arn:
|
|
398
|
+
gateway_arn = deployed.gateway_arn
|
|
399
|
+
if not target_name:
|
|
400
|
+
names = list((deployed.targets or {}).keys())
|
|
401
|
+
if len(names) > 1:
|
|
402
|
+
raise ValidationError(
|
|
403
|
+
f'Multiple targets found on gateway "{gateway}": {", ".join(names)}. '
|
|
404
|
+
"Use --target <name> to specify one."
|
|
405
|
+
)
|
|
406
|
+
target_name = names[0] if names else None
|
|
407
|
+
except ValidationError:
|
|
408
|
+
raise
|
|
409
|
+
except Exception: # noqa: BLE001 - deployed state unavailable; ARN is omitted
|
|
410
|
+
pass
|
|
411
|
+
|
|
412
|
+
statement = synthesize_cedar(
|
|
413
|
+
GuardrailFormConfig(category, filters, effect, data_path or default_data_path_for_effect(effect)),
|
|
414
|
+
target_name=target_name,
|
|
415
|
+
gateway_arn=gateway_arn,
|
|
416
|
+
)
|
|
417
|
+
return statement, authorization_phase_for_effect(effect)
|
|
418
|
+
|
|
419
|
+
# --- interactive (AddPolicyFlow / AddPolicyScreen) ----------------------------------
|
|
420
|
+
|
|
421
|
+
def add_interactive(self) -> None:
|
|
422
|
+
from agentcore.primitives.policy_engine import PRIMITIVE as engine_primitive
|
|
423
|
+
|
|
424
|
+
engines = engine_primitive.get_existing_engines()
|
|
425
|
+
if not engines:
|
|
426
|
+
engine_name = engine_primitive.run_engine_wizard(engines)
|
|
427
|
+
if not interactive.confirm("Add a policy to this engine?", default=True):
|
|
428
|
+
return
|
|
429
|
+
self.run_policy_wizard(engine_name, [*engines, engine_name])
|
|
430
|
+
return
|
|
431
|
+
choice = interactive.select(
|
|
432
|
+
"Add Policy",
|
|
433
|
+
[interactive.Choice(n, n, "Add a policy") for n in engines]
|
|
434
|
+
+ [interactive.Choice("Create a new policy engine", "__create_new__")],
|
|
435
|
+
)
|
|
436
|
+
if choice == "__create_new__":
|
|
437
|
+
engine_name = engine_primitive.run_engine_wizard(engines)
|
|
438
|
+
if not interactive.confirm("Add a policy to this engine?", default=True):
|
|
439
|
+
return
|
|
440
|
+
self.run_policy_wizard(engine_name, [*engines, engine_name])
|
|
441
|
+
else:
|
|
442
|
+
self.run_policy_wizard(choice, engines)
|
|
443
|
+
|
|
444
|
+
def run_policy_wizard(self, engine_name: str, existing_engines: list[str]) -> None:
|
|
445
|
+
"""Question order of useAddPolicyWizard with a pre-selected engine."""
|
|
446
|
+
from agentcore.primitives.policy_engine import PRIMITIVE as engine_primitive
|
|
447
|
+
|
|
448
|
+
deployed_id = engine_primitive.get_deployed_engine_id(engine_name)
|
|
449
|
+
deployed_gateways = engine_primitive.get_deployed_gateways()
|
|
450
|
+
project_gateways = engine_primitive.get_project_gateways()
|
|
451
|
+
is_engine_deployed = deployed_id is not None and len(deployed_gateways) > 0
|
|
452
|
+
|
|
453
|
+
gateway_name = ""
|
|
454
|
+
target_name = ""
|
|
455
|
+
if deployed_gateways:
|
|
456
|
+
gateway_name = interactive.select(
|
|
457
|
+
"Select a deployed gateway (choose which gateway this policy will apply to)",
|
|
458
|
+
[interactive.Choice(n, n, arn.split(":")[-1]) for n, arn in deployed_gateways.items()],
|
|
459
|
+
)
|
|
460
|
+
gw = next((g for g in project_gateways if g["name"] == gateway_name), None)
|
|
461
|
+
targets = gw["httpTargets"] if gw else []
|
|
462
|
+
if targets:
|
|
463
|
+
target_name = interactive.select(
|
|
464
|
+
f'Select an HTTP runtime target (targets on gateway "{gateway_name}")',
|
|
465
|
+
[interactive.Choice(t, t, "HTTP runtime target") for t in targets],
|
|
466
|
+
)
|
|
467
|
+
|
|
468
|
+
existing_policies = [
|
|
469
|
+
p["name"] for e in self._project()["policyEngines"] if e["name"] == engine_name for p in e["policies"]
|
|
470
|
+
]
|
|
471
|
+
|
|
472
|
+
def validate_name(value: str) -> str | None:
|
|
473
|
+
return first_issue(PolicyName, value) or (
|
|
474
|
+
"Policy name already exists" if value in existing_policies else None
|
|
475
|
+
)
|
|
476
|
+
|
|
477
|
+
name = interactive.text(
|
|
478
|
+
"Policy name", default=generate_unique_name("MyPolicy", existing_policies), validate=validate_name
|
|
479
|
+
)
|
|
480
|
+
|
|
481
|
+
method = interactive.select(
|
|
482
|
+
"How would you like to define the policy?",
|
|
483
|
+
[
|
|
484
|
+
interactive.Choice(
|
|
485
|
+
o.title,
|
|
486
|
+
o.id,
|
|
487
|
+
"Deploy engine first" if o.id == "generate" and not is_engine_deployed else o.description,
|
|
488
|
+
disabled="Deploy engine first" if o.id == "generate" and not is_engine_deployed else None,
|
|
489
|
+
)
|
|
490
|
+
for o in POLICY_SOURCE_METHOD_OPTIONS
|
|
491
|
+
],
|
|
492
|
+
)
|
|
493
|
+
|
|
494
|
+
statement = ""
|
|
495
|
+
source_file = ""
|
|
496
|
+
authorization_phase = "INITIATE"
|
|
497
|
+
source_display = "(inline statement)"
|
|
498
|
+
if method == "file":
|
|
499
|
+
source_file = interactive.text("Path to policy file (.cedar)")
|
|
500
|
+
source_display = source_file
|
|
501
|
+
elif method == "inline":
|
|
502
|
+
statement = interactive.text("Enter policy statement")
|
|
503
|
+
elif method == "generate":
|
|
504
|
+
statement, description = self._interactive_generate(engine_name, deployed_gateways)
|
|
505
|
+
source_display = f'Generated from: "{description}"'
|
|
506
|
+
elif method == "form":
|
|
507
|
+
statement, effect, form = self._interactive_form(
|
|
508
|
+
target_name, deployed_gateways.get(gateway_name) if gateway_name else None
|
|
509
|
+
)
|
|
510
|
+
authorization_phase = authorization_phase_for_effect(effect)
|
|
511
|
+
source_display = f"Form: {form.category} ({len(form.filters)} filters)"
|
|
512
|
+
|
|
513
|
+
enforcement = interactive.select(
|
|
514
|
+
"Enforcement mode (should this policy actively enforce decisions or only log them?)",
|
|
515
|
+
[interactive.Choice(o.title, o.id, o.description) for o in ENFORCEMENT_MODE_OPTIONS],
|
|
516
|
+
)
|
|
517
|
+
validation = interactive.select(
|
|
518
|
+
"Validation mode (how to handle analyzer validation findings)",
|
|
519
|
+
[interactive.Choice(o.title, o.id, o.description) for o in VALIDATION_MODE_OPTIONS],
|
|
520
|
+
)
|
|
521
|
+
|
|
522
|
+
typer.echo(f" Engine: {engine_name}")
|
|
523
|
+
typer.echo(f" Name: {name}")
|
|
524
|
+
typer.echo(f" Policy source: {source_display}")
|
|
525
|
+
typer.echo(f" Enforcement: {'Active' if enforcement == 'ACTIVE' else 'Log only'}")
|
|
526
|
+
typer.echo(
|
|
527
|
+
f" Validation: {'Fail on any findings' if validation == 'FAIL_ON_ANY_FINDINGS' else 'Ignore all findings'}"
|
|
528
|
+
)
|
|
529
|
+
if not interactive.confirm("Confirm?", default=True):
|
|
530
|
+
typer.echo("Cancelled.")
|
|
531
|
+
return
|
|
532
|
+
|
|
533
|
+
result = self.add(
|
|
534
|
+
AddPolicyOptions(
|
|
535
|
+
name=name,
|
|
536
|
+
engine=engine_name,
|
|
537
|
+
statement=statement,
|
|
538
|
+
source=source_file or None,
|
|
539
|
+
validation_mode=validation,
|
|
540
|
+
enforcement_mode=enforcement,
|
|
541
|
+
authorization_phase=authorization_phase,
|
|
542
|
+
)
|
|
543
|
+
)
|
|
544
|
+
if not result.success:
|
|
545
|
+
typer.echo("Failed to add policy resource", err=True)
|
|
546
|
+
raise result.error
|
|
547
|
+
typer.echo(f"Added policy: {name}")
|
|
548
|
+
typer.echo(f"Policy added to engine '{engine_name}'. Deploy with `agentcore deploy` to apply.")
|
|
549
|
+
|
|
550
|
+
def _interactive_generate(self, engine_name: str, deployed_gateways: dict[str, str]) -> tuple[str, str]:
|
|
551
|
+
from agentcore.primitives.policy_engine import PRIMITIVE as engine_primitive
|
|
552
|
+
|
|
553
|
+
gateway_arn = interactive.select(
|
|
554
|
+
"Select a deployed gateway (choose which gateway this policy will apply to)",
|
|
555
|
+
[interactive.Choice(n, arn, arn.split(":")[-1]) for n, arn in deployed_gateways.items()],
|
|
556
|
+
)
|
|
557
|
+
description = ""
|
|
558
|
+
while True:
|
|
559
|
+
description = interactive.text("Describe your policy in natural language", default=description)
|
|
560
|
+
typer.echo("Generating policy from description...")
|
|
561
|
+
try:
|
|
562
|
+
engine_id = engine_primitive.get_deployed_engine_id(engine_name)
|
|
563
|
+
if not engine_id:
|
|
564
|
+
raise Exception("Policy engine is not deployed. Run `agentcore deploy` first.")
|
|
565
|
+
statement = self._generate(engine_id, description, gateway_arn)
|
|
566
|
+
except Exception as exc: # noqa: BLE001
|
|
567
|
+
typer.echo(f"Generation failed: {get_error_message(exc)}", err=True)
|
|
568
|
+
continue
|
|
569
|
+
typer.echo("Generated policy:")
|
|
570
|
+
typer.secho(statement, fg="cyan")
|
|
571
|
+
if (
|
|
572
|
+
interactive.select(
|
|
573
|
+
"What would you like to do?",
|
|
574
|
+
[
|
|
575
|
+
interactive.Choice("Accept generated policy", "accept", "Use this policy"),
|
|
576
|
+
interactive.Choice("Regenerate", "regenerate", "Describe again and generate a new policy"),
|
|
577
|
+
],
|
|
578
|
+
)
|
|
579
|
+
== "accept"
|
|
580
|
+
):
|
|
581
|
+
return statement, description
|
|
582
|
+
|
|
583
|
+
def _interactive_form(self, target_name: str, gateway_arn: str | None) -> tuple[str, str, GuardrailFormConfig]:
|
|
584
|
+
while True:
|
|
585
|
+
effect = interactive.select(
|
|
586
|
+
"Policy effect (should this policy forbid or permit matching content?)",
|
|
587
|
+
[interactive.Choice(o.title, o.id, o.description) for o in POLICY_EFFECT_OPTIONS],
|
|
588
|
+
)
|
|
589
|
+
category = interactive.select(
|
|
590
|
+
"Select guardrail category",
|
|
591
|
+
[interactive.Choice(o.title, o.id, o.description) for o in GUARDRAIL_CATEGORY_OPTIONS],
|
|
592
|
+
)
|
|
593
|
+
filters: list[str] = interactive.checkbox(
|
|
594
|
+
f"Select filters for {category}",
|
|
595
|
+
[interactive.Choice(f, f) for f in FILTERS_BY_CATEGORY[category]],
|
|
596
|
+
)
|
|
597
|
+
while not filters:
|
|
598
|
+
filters = interactive.checkbox(
|
|
599
|
+
f"Select filters for {category} (select at least one)",
|
|
600
|
+
[interactive.Choice(f, f) for f in FILTERS_BY_CATEGORY[category]],
|
|
601
|
+
)
|
|
602
|
+
data_path = interactive.text(
|
|
603
|
+
"Data path to evaluate (e.g. context.input.prompt, context.output.prompt)",
|
|
604
|
+
default=default_data_path_for_effect(effect),
|
|
605
|
+
)
|
|
606
|
+
form = GuardrailFormConfig(category, filters, effect, data_path)
|
|
607
|
+
cedar = synthesize_cedar(form, target_name=target_name or None, gateway_arn=gateway_arn)
|
|
608
|
+
typer.echo("Generated policy from guardrail form:")
|
|
609
|
+
typer.secho(cedar, fg="cyan")
|
|
610
|
+
typer.echo("Authorization phase: INITIATE (default)")
|
|
611
|
+
choice = interactive.select(
|
|
612
|
+
"What would you like to do?",
|
|
613
|
+
[
|
|
614
|
+
interactive.Choice("Accept policy", "accept", "Use this generated policy"),
|
|
615
|
+
interactive.Choice("Edit selections", "edit", "Go back and change filters/thresholds"),
|
|
616
|
+
],
|
|
617
|
+
)
|
|
618
|
+
if choice == "accept":
|
|
619
|
+
return cedar, effect, form
|
|
620
|
+
|
|
621
|
+
|
|
622
|
+
PRIMITIVE = PolicyPrimitive()
|