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,266 @@
|
|
|
1
|
+
"""Interactive shell over WebSocket (port of ``connect-shell.ts``).
|
|
2
|
+
|
|
3
|
+
Uses the ``websockets`` synchronous client. The upgrade request is SigV4-signed (service
|
|
4
|
+
``bedrock-agentcore``) unless a bearer token is supplied, in which case the token travels in the
|
|
5
|
+
``base64UrlBearerAuthorization`` WebSocket subprotocol and signing is skipped.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import base64
|
|
11
|
+
import random
|
|
12
|
+
import ssl
|
|
13
|
+
import threading
|
|
14
|
+
import time
|
|
15
|
+
from collections.abc import Callable, Mapping
|
|
16
|
+
from dataclasses import dataclass, field
|
|
17
|
+
from typing import Any
|
|
18
|
+
from urllib.parse import urlencode, urlsplit
|
|
19
|
+
|
|
20
|
+
from botocore.httpsession import get_cert_path
|
|
21
|
+
|
|
22
|
+
from agentcore.aws._http import encode_uri_component, sign_headers
|
|
23
|
+
from agentcore.aws.stage_endpoint import data_plane_endpoint
|
|
24
|
+
from agentcore.lib.errors.types import ShellKickedError
|
|
25
|
+
|
|
26
|
+
SHELL_ID_HEADER = "x-amzn-bedrock-agentcore-shell-id"
|
|
27
|
+
SESSION_ID_HEADER = "X-Amzn-Bedrock-AgentCore-Runtime-Session-Id"
|
|
28
|
+
KICKED_CLOSE_CODE = 4000
|
|
29
|
+
|
|
30
|
+
PING_INTERVAL_S = 30.0
|
|
31
|
+
PONG_TIMEOUT_S = 60.0
|
|
32
|
+
_OUTER_DELAY_S = 30.0
|
|
33
|
+
_TOTAL_WINDOW_S = 15 * 60.0
|
|
34
|
+
|
|
35
|
+
# Indirection points for tests.
|
|
36
|
+
_sleep = time.sleep
|
|
37
|
+
_now = time.monotonic
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@dataclass(slots=True)
|
|
41
|
+
class ShellReconnectOptions:
|
|
42
|
+
max_retries: int = 5
|
|
43
|
+
"""Maximum number of attempts; 0 = unlimited."""
|
|
44
|
+
base_delay: float = 1
|
|
45
|
+
"""Initial delay in seconds between retries; doubles each attempt."""
|
|
46
|
+
max_delay: float = 15
|
|
47
|
+
on_attempt: Callable[[int, str], None] | None = None
|
|
48
|
+
"""Called at the start of each reconnect attempt."""
|
|
49
|
+
on_kicked: Callable[[], None] | None = None
|
|
50
|
+
"""Called on close code 4000 (another client took the session)."""
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@dataclass(slots=True)
|
|
54
|
+
class ShellConnection:
|
|
55
|
+
ws: Any
|
|
56
|
+
"""The open ``websockets.sync.client.ClientConnection``."""
|
|
57
|
+
shell_id: str
|
|
58
|
+
"""Server-assigned shell identifier (from the 101 upgrade response header)."""
|
|
59
|
+
session_id: str | None = None
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@dataclass(slots=True)
|
|
63
|
+
class _OpenResult:
|
|
64
|
+
ws: Any
|
|
65
|
+
response_headers: Mapping[str, str] = field(default_factory=dict)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def build_shell_url(region: str, runtime_arn: str, shell_id: str | None = None) -> str:
|
|
69
|
+
"""``wss://`` URL of the shell endpoint (respects ``AGENTCORE_STAGE``)."""
|
|
70
|
+
host = urlsplit(data_plane_endpoint(region)).netloc
|
|
71
|
+
params = {"qualifier": "DEFAULT"}
|
|
72
|
+
if shell_id:
|
|
73
|
+
params["shellId"] = shell_id
|
|
74
|
+
return f"wss://{host}/runtimes/{encode_uri_component(runtime_arn)}/ws/shells?{urlencode(params)}"
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def translate_upgrade_error(err: BaseException) -> BaseException:
|
|
78
|
+
"""Map WebSocket upgrade HTTP failures to actionable messages."""
|
|
79
|
+
msg = str(err)
|
|
80
|
+
if "424" in msg or "Failed Dependency" in msg:
|
|
81
|
+
return RuntimeError("Agent VM is not ready (error 424). Run `agentcore status` to check deployment.")
|
|
82
|
+
if "429" in msg or "Too Many" in msg:
|
|
83
|
+
return RuntimeError("Maximum terminal sessions reached (10). Close an existing session and retry.")
|
|
84
|
+
if "403" in msg or "Forbidden" in msg:
|
|
85
|
+
return RuntimeError(
|
|
86
|
+
"Access denied (403). Check IAM permission bedrock-agentcore:InvokeAgentRuntimeCommandWithWebSocketStream."
|
|
87
|
+
)
|
|
88
|
+
return err
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def _ws_connect(url: str, headers: Mapping[str, str], subprotocols: list[str] | None) -> _OpenResult:
|
|
92
|
+
from websockets.sync.client import connect
|
|
93
|
+
|
|
94
|
+
ssl_context = ssl.create_default_context(cafile=get_cert_path(True))
|
|
95
|
+
ws = connect(
|
|
96
|
+
url,
|
|
97
|
+
additional_headers=dict(headers),
|
|
98
|
+
subprotocols=subprotocols, # type: ignore[arg-type]
|
|
99
|
+
ssl=ssl_context,
|
|
100
|
+
proxy=None,
|
|
101
|
+
ping_interval=None, # keepalive is managed explicitly via start_keepalive()
|
|
102
|
+
ping_timeout=None,
|
|
103
|
+
max_size=100 * 1024 * 1024,
|
|
104
|
+
)
|
|
105
|
+
response = ws.response
|
|
106
|
+
return _OpenResult(ws=ws, response_headers=response.headers if response is not None else {})
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def _close_code(err: BaseException) -> int | None:
|
|
110
|
+
rcvd = getattr(err, "rcvd", None)
|
|
111
|
+
return getattr(rcvd, "code", None) if rcvd is not None else getattr(err, "code", None)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def _open_websocket(
|
|
115
|
+
*,
|
|
116
|
+
region: str,
|
|
117
|
+
runtime_arn: str,
|
|
118
|
+
session_id: str | None,
|
|
119
|
+
shell_id: str | None,
|
|
120
|
+
headers: Mapping[str, str] | None,
|
|
121
|
+
bearer_token: str | None,
|
|
122
|
+
) -> ShellConnection:
|
|
123
|
+
url = build_shell_url(region, runtime_arn, shell_id)
|
|
124
|
+
extra_headers = dict(headers or {})
|
|
125
|
+
if session_id:
|
|
126
|
+
extra_headers[SESSION_ID_HEADER] = session_id
|
|
127
|
+
|
|
128
|
+
subprotocols: list[str] | None = None
|
|
129
|
+
if bearer_token:
|
|
130
|
+
# CUSTOM_JWT: Sec-WebSocket-Protocol: base64UrlBearerAuthorization.<b64url>, base64UrlBearerAuthorization
|
|
131
|
+
encoded = base64.urlsafe_b64encode(bearer_token.encode("utf-8")).rstrip(b"=").decode("ascii")
|
|
132
|
+
subprotocols = [f"base64UrlBearerAuthorization.{encoded}", "base64UrlBearerAuthorization"]
|
|
133
|
+
request_headers = extra_headers
|
|
134
|
+
else:
|
|
135
|
+
https_url = "https://" + url[len("wss://") :]
|
|
136
|
+
signed = sign_headers("GET", https_url, region=region, headers=extra_headers)
|
|
137
|
+
# The websocket client writes its own Host header (identical to the signed one).
|
|
138
|
+
request_headers = {k: v for k, v in signed.items() if k.lower() != "host"}
|
|
139
|
+
|
|
140
|
+
try:
|
|
141
|
+
opened = _ws_connect(url, request_headers, subprotocols)
|
|
142
|
+
except Exception as exc:
|
|
143
|
+
code = _close_code(exc)
|
|
144
|
+
if code == KICKED_CLOSE_CODE:
|
|
145
|
+
raise ShellKickedError() from exc
|
|
146
|
+
if isinstance(code, int):
|
|
147
|
+
raise RuntimeError(f"WebSocket closed before open (code {code})") from exc # noqa: TRY004
|
|
148
|
+
translated = translate_upgrade_error(exc)
|
|
149
|
+
if translated is exc:
|
|
150
|
+
raise
|
|
151
|
+
raise translated from exc
|
|
152
|
+
|
|
153
|
+
header_shell_id = opened.response_headers.get(SHELL_ID_HEADER) if opened.response_headers else None
|
|
154
|
+
resolved = header_shell_id or shell_id
|
|
155
|
+
if not resolved:
|
|
156
|
+
# An empty shell ID silently breaks reconnect, so treat a missing header as a failure.
|
|
157
|
+
try:
|
|
158
|
+
opened.ws.close()
|
|
159
|
+
except Exception: # noqa: BLE001, S110
|
|
160
|
+
pass
|
|
161
|
+
raise RuntimeError(
|
|
162
|
+
"Shell session could not be established: the server did not return a shell ID. "
|
|
163
|
+
"Retry, or run `agentcore status` to check the runtime."
|
|
164
|
+
)
|
|
165
|
+
return ShellConnection(ws=opened.ws, shell_id=resolved, session_id=session_id)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def start_keepalive(
|
|
169
|
+
ws: Any,
|
|
170
|
+
on_dead: Callable[[], None],
|
|
171
|
+
*,
|
|
172
|
+
ping_interval: float = PING_INTERVAL_S,
|
|
173
|
+
pong_timeout: float = PONG_TIMEOUT_S,
|
|
174
|
+
) -> Callable[[], None]:
|
|
175
|
+
"""Send RFC 6455 pings every ``ping_interval`` seconds; call ``on_dead`` if a pong is late.
|
|
176
|
+
|
|
177
|
+
Returns a ``stop`` function that cancels the keepalive.
|
|
178
|
+
"""
|
|
179
|
+
stopped = threading.Event()
|
|
180
|
+
timers: list[threading.Timer] = []
|
|
181
|
+
|
|
182
|
+
def check_pong(pong: threading.Event) -> None:
|
|
183
|
+
if not stopped.is_set() and not pong.is_set():
|
|
184
|
+
on_dead()
|
|
185
|
+
|
|
186
|
+
def loop() -> None:
|
|
187
|
+
while not stopped.wait(ping_interval):
|
|
188
|
+
try:
|
|
189
|
+
pong = ws.ping()
|
|
190
|
+
except Exception: # noqa: BLE001, S112 - socket not open; skip this tick
|
|
191
|
+
continue
|
|
192
|
+
timer = threading.Timer(pong_timeout, check_pong, args=(pong,))
|
|
193
|
+
timer.daemon = True
|
|
194
|
+
timers.append(timer)
|
|
195
|
+
timer.start()
|
|
196
|
+
|
|
197
|
+
thread = threading.Thread(target=loop, name="agentcore-shell-keepalive", daemon=True)
|
|
198
|
+
thread.start()
|
|
199
|
+
|
|
200
|
+
def stop() -> None:
|
|
201
|
+
stopped.set()
|
|
202
|
+
for timer in timers:
|
|
203
|
+
timer.cancel()
|
|
204
|
+
|
|
205
|
+
return stop
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
def _jitter(seconds: float) -> float:
|
|
209
|
+
return seconds * (0.75 + random.random() * 0.5)
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def connect_shell(
|
|
213
|
+
*,
|
|
214
|
+
region: str,
|
|
215
|
+
runtime_arn: str,
|
|
216
|
+
session_id: str | None = None,
|
|
217
|
+
shell_id: str | None = None,
|
|
218
|
+
headers: Mapping[str, str] | None = None,
|
|
219
|
+
reconnect: ShellReconnectOptions | None = None,
|
|
220
|
+
bearer_token: str | None = None,
|
|
221
|
+
) -> ShellConnection:
|
|
222
|
+
"""Open a shell WebSocket, retrying the initial handshake when ``reconnect`` is given.
|
|
223
|
+
|
|
224
|
+
Mid-session reconnects are the caller's responsibility. Raises :class:`ShellKickedError` on
|
|
225
|
+
close code 4000 (never retried).
|
|
226
|
+
"""
|
|
227
|
+
|
|
228
|
+
def attempt(current_shell_id: str | None) -> ShellConnection:
|
|
229
|
+
return _open_websocket(
|
|
230
|
+
region=region,
|
|
231
|
+
runtime_arn=runtime_arn,
|
|
232
|
+
session_id=session_id,
|
|
233
|
+
shell_id=current_shell_id,
|
|
234
|
+
headers=headers,
|
|
235
|
+
bearer_token=bearer_token,
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
if reconnect is None:
|
|
239
|
+
return attempt(shell_id)
|
|
240
|
+
|
|
241
|
+
start = _now()
|
|
242
|
+
attempts = 0
|
|
243
|
+
while True:
|
|
244
|
+
try:
|
|
245
|
+
return attempt(shell_id)
|
|
246
|
+
except ShellKickedError:
|
|
247
|
+
if reconnect.on_kicked:
|
|
248
|
+
reconnect.on_kicked()
|
|
249
|
+
raise
|
|
250
|
+
except Exception as exc:
|
|
251
|
+
attempts += 1
|
|
252
|
+
reason = str(exc)
|
|
253
|
+
if reconnect.on_attempt:
|
|
254
|
+
reconnect.on_attempt(attempts, reason)
|
|
255
|
+
|
|
256
|
+
# No sleep after the final attempt so the caller sees the error immediately.
|
|
257
|
+
if reconnect.max_retries > 0 and attempts >= reconnect.max_retries:
|
|
258
|
+
raise
|
|
259
|
+
if _now() - start > _TOTAL_WINDOW_S:
|
|
260
|
+
raise
|
|
261
|
+
|
|
262
|
+
# 1s -> 2s -> 4s -> 8s -> 15s (capped), +/-25% jitter; extra 30s pause every 5 attempts.
|
|
263
|
+
inner = min(reconnect.base_delay * 2 ** min(attempts - 1, 4), reconnect.max_delay)
|
|
264
|
+
_sleep(_jitter(inner))
|
|
265
|
+
if attempts % 5 == 0:
|
|
266
|
+
_sleep(_OUTER_DELAY_S)
|
agentcore/aws/iam.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""IAM trust-policy validation (port of ``iam.ts``)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from typing import Any
|
|
7
|
+
from urllib.parse import unquote
|
|
8
|
+
|
|
9
|
+
from agentcore.lib.errors.types import ValidationError
|
|
10
|
+
|
|
11
|
+
IamPolicyDocument = dict[str, Any]
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _parse_iam_policy_document(policy: object) -> object:
|
|
15
|
+
if not isinstance(policy, str):
|
|
16
|
+
return policy
|
|
17
|
+
try:
|
|
18
|
+
return json.loads(unquote(policy, errors="strict"))
|
|
19
|
+
except (ValueError, UnicodeDecodeError):
|
|
20
|
+
return None
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _stable_stringify(value: object) -> str:
|
|
24
|
+
# fast-json-stable-stringify: recursively sorted keys, compact separators.
|
|
25
|
+
return json.dumps(value, sort_keys=True, separators=(",", ":"), ensure_ascii=False)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def validate_iam_role_trust_policy(
|
|
29
|
+
actual_policy: object, expected_policy: IamPolicyDocument, role_name: str, remediation: str
|
|
30
|
+
) -> None:
|
|
31
|
+
"""Raise unless the role's trust policy structurally matches ``expected_policy``.
|
|
32
|
+
|
|
33
|
+
IAM may return ``AssumeRolePolicyDocument`` as an object or a URL-encoded JSON string.
|
|
34
|
+
"""
|
|
35
|
+
parsed = _parse_iam_policy_document(actual_policy)
|
|
36
|
+
if isinstance(parsed, dict) and _stable_stringify(parsed) == _stable_stringify(expected_policy):
|
|
37
|
+
return
|
|
38
|
+
raise ValidationError(
|
|
39
|
+
f'Refusing to reuse existing IAM role "{role_name}" because its trust policy does not match '
|
|
40
|
+
f"the policy required by AgentCore. {remediation}"
|
|
41
|
+
)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"""Partition-aware ARN/endpoint helpers (port of ``partition.ts``).
|
|
2
|
+
|
|
3
|
+
Upstream resolves partitions with ``@aws-sdk/util-endpoints``; botocore ships the same
|
|
4
|
+
``partitions.json`` data, so resolution follows the same rules: explicit region membership first,
|
|
5
|
+
then the partition's ``regionRegex``, falling back to the ``aws`` partition.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import re
|
|
11
|
+
from functools import lru_cache
|
|
12
|
+
from typing import Any
|
|
13
|
+
|
|
14
|
+
from botocore.loaders import Loader
|
|
15
|
+
|
|
16
|
+
_CONSOLE_DOMAINS = {
|
|
17
|
+
"aws-us-gov": "console.amazonaws-us-gov.com",
|
|
18
|
+
"aws-cn": "console.amazonaws.cn",
|
|
19
|
+
}
|
|
20
|
+
_DEFAULT_CONSOLE_DOMAIN = "console.aws.amazon.com"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@lru_cache(maxsize=1)
|
|
24
|
+
def _partitions() -> list[dict[str, Any]]:
|
|
25
|
+
return Loader().load_data("partitions")["partitions"]
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@lru_cache(maxsize=256)
|
|
29
|
+
def _partition_for(region: str) -> tuple[str, str]:
|
|
30
|
+
partitions = _partitions()
|
|
31
|
+
for p in partitions:
|
|
32
|
+
if region in p.get("regions", {}):
|
|
33
|
+
return p["id"], p["outputs"]["dnsSuffix"]
|
|
34
|
+
for p in partitions:
|
|
35
|
+
if re.match(p["regionRegex"], region):
|
|
36
|
+
return p["id"], p["outputs"]["dnsSuffix"]
|
|
37
|
+
aws = next(p for p in partitions if p["id"] == "aws")
|
|
38
|
+
return aws["id"], aws["outputs"]["dnsSuffix"]
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def get_partition(region: str) -> str:
|
|
42
|
+
return _partition_for(region)[0]
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def arn_prefix(region: str) -> str:
|
|
46
|
+
return f"arn:{get_partition(region)}"
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def dns_suffix(region: str) -> str:
|
|
50
|
+
return _partition_for(region)[1]
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def service_endpoint(service: str, region: str) -> str:
|
|
54
|
+
return f"{service}.{region}.{dns_suffix(region)}"
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def console_domain(region: str) -> str:
|
|
58
|
+
return _CONSOLE_DOMAINS.get(get_partition(region), _DEFAULT_CONSOLE_DOMAIN)
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"""Cedar policy generation (port of ``policy-generation.ts``)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import time
|
|
6
|
+
from typing import TypedDict
|
|
7
|
+
|
|
8
|
+
from agentcore.aws.account import create_aws_client
|
|
9
|
+
|
|
10
|
+
# Mirrors the SDK waiter options upstream passes (maxWaitTime 120s, minDelay 2s, maxDelay 5s).
|
|
11
|
+
_WAIT_MAX_S = 120.0
|
|
12
|
+
_WAIT_MIN_DELAY_S = 2.0
|
|
13
|
+
_WAIT_MAX_DELAY_S = 5.0
|
|
14
|
+
_SUCCESS_STATES = frozenset({"GENERATED"})
|
|
15
|
+
_FAILURE_STATES = frozenset({"GENERATE_FAILED", "DELETE_FAILED"})
|
|
16
|
+
|
|
17
|
+
# Indirection points for tests.
|
|
18
|
+
_sleep = time.sleep
|
|
19
|
+
_now = time.monotonic
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class StartPolicyGenerationResult(TypedDict):
|
|
23
|
+
generationId: str
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class GetPolicyGenerationResult(TypedDict):
|
|
27
|
+
status: str
|
|
28
|
+
statement: str
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def start_policy_generation(
|
|
32
|
+
*, policy_engine_id: str, description: str, region: str, resource_arn: str
|
|
33
|
+
) -> StartPolicyGenerationResult:
|
|
34
|
+
client = create_aws_client("bedrock-agentcore-control", region)
|
|
35
|
+
response = client.start_policy_generation(
|
|
36
|
+
policyEngineId=policy_engine_id,
|
|
37
|
+
resource={"arn": resource_arn},
|
|
38
|
+
content={"rawText": description},
|
|
39
|
+
name=f"cli_generation_{int(time.time() * 1000)}",
|
|
40
|
+
)
|
|
41
|
+
generation_id = response.get("policyGenerationId")
|
|
42
|
+
if not generation_id:
|
|
43
|
+
raise RuntimeError("No generation ID returned from StartPolicyGeneration")
|
|
44
|
+
return {"generationId": generation_id}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _wait_for_generation(client: object, generation_id: str, policy_engine_id: str) -> str:
|
|
48
|
+
"""Poll ``GetPolicyGeneration`` until a terminal status; returns ``SUCCESS``/``FAILURE``/``TIMEOUT``.
|
|
49
|
+
|
|
50
|
+
Like the SDK waiter, request errors are treated as "retry".
|
|
51
|
+
"""
|
|
52
|
+
start = _now()
|
|
53
|
+
attempt = 0
|
|
54
|
+
while True:
|
|
55
|
+
attempt += 1
|
|
56
|
+
try:
|
|
57
|
+
status = client.get_policy_generation( # type: ignore[attr-defined]
|
|
58
|
+
policyGenerationId=generation_id, policyEngineId=policy_engine_id
|
|
59
|
+
).get("status")
|
|
60
|
+
if status in _SUCCESS_STATES:
|
|
61
|
+
return "SUCCESS"
|
|
62
|
+
if status in _FAILURE_STATES:
|
|
63
|
+
return "FAILURE"
|
|
64
|
+
except Exception: # noqa: BLE001, S110
|
|
65
|
+
pass
|
|
66
|
+
delay = min(_WAIT_MIN_DELAY_S * 2 ** (attempt - 1), _WAIT_MAX_DELAY_S)
|
|
67
|
+
if _now() - start + delay > _WAIT_MAX_S:
|
|
68
|
+
return "TIMEOUT"
|
|
69
|
+
_sleep(delay)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _finding_text(finding: dict) -> str | None:
|
|
73
|
+
description = finding.get("description")
|
|
74
|
+
return description if description is not None else finding.get("type")
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def get_policy_generation(*, generation_id: str, policy_engine_id: str, region: str) -> GetPolicyGenerationResult:
|
|
78
|
+
"""Wait for a generation to finish and return its first Cedar statement."""
|
|
79
|
+
client = create_aws_client("bedrock-agentcore-control", region)
|
|
80
|
+
|
|
81
|
+
state = _wait_for_generation(client, generation_id, policy_engine_id)
|
|
82
|
+
# A FAILURE state falls through so the status check below reports the service's reasons.
|
|
83
|
+
if state == "TIMEOUT":
|
|
84
|
+
raise RuntimeError(
|
|
85
|
+
f"Policy generation did not complete within the timeout period (state: {state}). "
|
|
86
|
+
f"Generation ID: {generation_id}"
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
status_response = client.get_policy_generation(policyGenerationId=generation_id, policyEngineId=policy_engine_id)
|
|
90
|
+
if status_response.get("status") == "GENERATE_FAILED":
|
|
91
|
+
reasons = status_response.get("statusReasons")
|
|
92
|
+
raise RuntimeError(
|
|
93
|
+
f"Policy generation failed: {', '.join(reasons) if reasons is not None else 'Unknown reason'}"
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
assets = (
|
|
97
|
+
client.list_policy_generation_assets(policyGenerationId=generation_id, policyEngineId=policy_engine_id).get(
|
|
98
|
+
"policyGenerationAssets"
|
|
99
|
+
)
|
|
100
|
+
or []
|
|
101
|
+
)
|
|
102
|
+
if not assets:
|
|
103
|
+
raise RuntimeError("Policy generation completed but no assets were returned")
|
|
104
|
+
|
|
105
|
+
first = assets[0]
|
|
106
|
+
definition = first.get("definition") or {}
|
|
107
|
+
statement = (definition.get("cedar") or {}).get("statement") or (definition.get("policy") or {}).get("statement")
|
|
108
|
+
if not statement:
|
|
109
|
+
findings = first.get("findings")
|
|
110
|
+
details = ", ".join(d for d in (_finding_text(f) for f in findings) if d) if findings is not None else ""
|
|
111
|
+
raise RuntimeError(
|
|
112
|
+
"Policy generation completed but no policy statement was found in the assets"
|
|
113
|
+
+ (f": {details}" if details else "")
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
return {"status": status_response.get("status") or "GENERATED", "statement": statement}
|
agentcore/aws/region.py
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"""Ambient region detection (port of ``region.ts``)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from typing import Literal, cast
|
|
8
|
+
|
|
9
|
+
import botocore.session
|
|
10
|
+
|
|
11
|
+
from agentcore.schema.schemas.aws_targets import AGENTCORE_REGIONS, AgentCoreRegion
|
|
12
|
+
|
|
13
|
+
DEFAULT_REGION: AgentCoreRegion = "us-east-1"
|
|
14
|
+
|
|
15
|
+
RegionSource = Literal["env", "config", "default"]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass(frozen=True, slots=True)
|
|
19
|
+
class RegionDetectionResult:
|
|
20
|
+
region: AgentCoreRegion
|
|
21
|
+
source: RegionSource
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _is_agentcore_region(region: str) -> bool:
|
|
25
|
+
return region in AGENTCORE_REGIONS
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _load_profile_config(profile: str) -> dict[str, object]:
|
|
29
|
+
# Same view as @smithy/shared-ini-file-loader's configFile: ~/.aws/config (or AWS_CONFIG_FILE)
|
|
30
|
+
# with "profile " prefixes stripped.
|
|
31
|
+
profiles = botocore.session.Session().full_config.get("profiles", {})
|
|
32
|
+
return profiles.get(profile, {}) or {}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def detect_region() -> RegionDetectionResult:
|
|
36
|
+
"""Priority: ``AWS_REGION`` > ``AWS_DEFAULT_REGION`` > profile config > ``us-east-1``.
|
|
37
|
+
|
|
38
|
+
Only AgentCore-supported regions are accepted from each source.
|
|
39
|
+
"""
|
|
40
|
+
env_region = os.environ.get("AWS_REGION")
|
|
41
|
+
if env_region is None:
|
|
42
|
+
env_region = os.environ.get("AWS_DEFAULT_REGION")
|
|
43
|
+
if env_region and _is_agentcore_region(env_region):
|
|
44
|
+
return RegionDetectionResult(cast(AgentCoreRegion, env_region), "env")
|
|
45
|
+
|
|
46
|
+
try:
|
|
47
|
+
profile = os.environ.get("AWS_PROFILE") or "default"
|
|
48
|
+
config_region = _load_profile_config(profile).get("region")
|
|
49
|
+
if isinstance(config_region, str) and _is_agentcore_region(config_region):
|
|
50
|
+
return RegionDetectionResult(cast(AgentCoreRegion, config_region), "config")
|
|
51
|
+
except Exception: # noqa: BLE001, S110 - config file missing or unparsable
|
|
52
|
+
pass
|
|
53
|
+
|
|
54
|
+
return RegionDetectionResult(DEFAULT_REGION, "default")
|
agentcore/aws/retry.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""AWS error-retryability helpers (port of ``retry.ts``).
|
|
2
|
+
|
|
3
|
+
Mirrors the signals the AWS SDK's retry middleware uses: name-based throttling/transient sets
|
|
4
|
+
plus an HTTP status fallback. No message matching.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import re
|
|
10
|
+
|
|
11
|
+
from agentcore.aws._aws_errors import aws_error_name, aws_http_status
|
|
12
|
+
|
|
13
|
+
_THROTTLING_NAME = re.compile(
|
|
14
|
+
r"^(Throttling|TooManyRequests|RequestLimitExceeded|LimitExceeded)(Exception)?$", re.IGNORECASE
|
|
15
|
+
)
|
|
16
|
+
_TRANSIENT_NAME = re.compile(r"^(ServiceUnavailable|InternalServer|InternalFailure)(Exception)?$", re.IGNORECASE)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def is_retryable_aws_error(err: object) -> bool:
|
|
20
|
+
"""True if ``err`` is a transient AWS error worth retrying."""
|
|
21
|
+
name = aws_error_name(err) or ""
|
|
22
|
+
if _THROTTLING_NAME.match(name) or _TRANSIENT_NAME.match(name):
|
|
23
|
+
return True
|
|
24
|
+
status = aws_http_status(err)
|
|
25
|
+
if status == 429:
|
|
26
|
+
return True
|
|
27
|
+
return status is not None and 500 <= status < 600
|