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,442 @@
|
|
|
1
|
+
"""Port of commands/exec/action.ts: one-shot and interactive (PTY over WebSocket) exec."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import queue
|
|
5
|
+
import select
|
|
6
|
+
import shutil
|
|
7
|
+
import signal
|
|
8
|
+
import sys
|
|
9
|
+
import threading
|
|
10
|
+
import time
|
|
11
|
+
import uuid
|
|
12
|
+
from dataclasses import dataclass
|
|
13
|
+
from typing import Any
|
|
14
|
+
|
|
15
|
+
from agentcore.aws.agentcore import ExecuteBashOptions, execute_bash_command
|
|
16
|
+
from agentcore.aws.arn import region_from_arn
|
|
17
|
+
from agentcore.aws.connect_shell import ShellReconnectOptions, connect_shell, start_keepalive
|
|
18
|
+
from agentcore.aws.shell_framer import ShellChannel, ShellFramer, parse_status_frame
|
|
19
|
+
from agentcore.cli.commands.exec.types import ExecOptions, ExecResult
|
|
20
|
+
from agentcore.lib.schemas.io.config_io import ConfigIO
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@dataclass
|
|
24
|
+
class ExecContext:
|
|
25
|
+
region: str
|
|
26
|
+
runtime_arn: str
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _is_harness_arn(arn: str) -> bool:
|
|
30
|
+
return ":harness/" in arn
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _assert_interactive_harness_unsupported(options: ExecOptions, ctx: ExecContext) -> ExecContext:
|
|
34
|
+
"""The data plane rejects interactive shells on harness-linked runtimes; one-shot exec works."""
|
|
35
|
+
if options.interactive and _is_harness_arn(ctx.runtime_arn):
|
|
36
|
+
raise RuntimeError(
|
|
37
|
+
"Interactive shell (--it) is not supported for harness deployments yet. "
|
|
38
|
+
'Use one-shot exec instead, e.g. `agentcore exec "<command>"`.'
|
|
39
|
+
)
|
|
40
|
+
return ctx
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _harness_arn_error(value: str) -> RuntimeError:
|
|
44
|
+
return RuntimeError(
|
|
45
|
+
f"--harness expects a harness ARN (…:harness/…), got '{value}'. Use --runtime for a runtime ARN."
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def load_exec_context(options: ExecOptions, config_io: ConfigIO | None = None) -> ExecContext:
|
|
50
|
+
"""Resolve region + target ARN. A full ARN needs no project; a name is looked up in deployed state."""
|
|
51
|
+
if options.runtime_arn and options.harness_name:
|
|
52
|
+
raise RuntimeError("Cannot specify both --runtime and --harness.")
|
|
53
|
+
|
|
54
|
+
if options.runtime_arn and options.runtime_arn.startswith("arn:"):
|
|
55
|
+
region = options.region or region_from_arn(options.runtime_arn)
|
|
56
|
+
if region:
|
|
57
|
+
return _assert_interactive_harness_unsupported(options, ExecContext(region, options.runtime_arn))
|
|
58
|
+
|
|
59
|
+
if options.harness_name and options.harness_name.startswith("arn:"):
|
|
60
|
+
if not _is_harness_arn(options.harness_name):
|
|
61
|
+
raise _harness_arn_error(options.harness_name)
|
|
62
|
+
region = options.region or region_from_arn(options.harness_name)
|
|
63
|
+
if region:
|
|
64
|
+
return _assert_interactive_harness_unsupported(options, ExecContext(region, options.harness_name))
|
|
65
|
+
|
|
66
|
+
config_io = config_io or ConfigIO()
|
|
67
|
+
aws_targets = config_io.read_aws_deployment_targets()
|
|
68
|
+
deployed_state = config_io.read_deployed_state()
|
|
69
|
+
|
|
70
|
+
targets = deployed_state.targets or {}
|
|
71
|
+
target_names = list(targets)
|
|
72
|
+
if not target_names:
|
|
73
|
+
raise RuntimeError("No deployed targets found. Run `agentcore deploy` first.")
|
|
74
|
+
if options.target_name and options.target_name not in target_names:
|
|
75
|
+
raise RuntimeError(
|
|
76
|
+
f"Deployment target '{options.target_name}' not found. Available targets: {', '.join(target_names)}"
|
|
77
|
+
)
|
|
78
|
+
target_name = options.target_name or target_names[0]
|
|
79
|
+
target_config = next((t for t in aws_targets if t.name == target_name), None)
|
|
80
|
+
if target_config is None:
|
|
81
|
+
raise RuntimeError(f"Deployment target config '{target_name}' not found in aws-targets.")
|
|
82
|
+
|
|
83
|
+
target_state = targets.get(target_name)
|
|
84
|
+
resources = target_state.resources if target_state else None
|
|
85
|
+
runtimes = (resources.runtimes if resources else None) or {}
|
|
86
|
+
harnesses = (resources.harnesses if resources else None) or {}
|
|
87
|
+
region = options.region or target_config.region
|
|
88
|
+
|
|
89
|
+
if options.runtime_arn and options.runtime_arn.startswith("arn:"):
|
|
90
|
+
return _assert_interactive_harness_unsupported(options, ExecContext(region, options.runtime_arn))
|
|
91
|
+
|
|
92
|
+
if options.harness_name:
|
|
93
|
+
if options.harness_name.startswith("arn:"):
|
|
94
|
+
if not _is_harness_arn(options.harness_name):
|
|
95
|
+
raise _harness_arn_error(options.harness_name)
|
|
96
|
+
return _assert_interactive_harness_unsupported(options, ExecContext(region, options.harness_name))
|
|
97
|
+
harness_state = harnesses.get(options.harness_name)
|
|
98
|
+
if not harness_state:
|
|
99
|
+
raise RuntimeError(
|
|
100
|
+
f"Harness '{options.harness_name}' not found in target '{target_name}'. "
|
|
101
|
+
f"Available harnesses: {', '.join(harnesses)}"
|
|
102
|
+
)
|
|
103
|
+
return _assert_interactive_harness_unsupported(options, ExecContext(region, harness_state.harness_arn))
|
|
104
|
+
|
|
105
|
+
if options.runtime_arn:
|
|
106
|
+
agent_state = runtimes.get(options.runtime_arn)
|
|
107
|
+
if not agent_state or not agent_state.runtime_arn:
|
|
108
|
+
raise RuntimeError(
|
|
109
|
+
f"Agent '{options.runtime_arn}' not found in target '{target_name}'. "
|
|
110
|
+
f"Available agents: {', '.join(runtimes)}"
|
|
111
|
+
)
|
|
112
|
+
return _assert_interactive_harness_unsupported(options, ExecContext(region, agent_state.runtime_arn))
|
|
113
|
+
|
|
114
|
+
candidates = [r.runtime_arn for r in runtimes.values()] + [h.harness_arn for h in harnesses.values()]
|
|
115
|
+
candidates = [c for c in candidates if c]
|
|
116
|
+
if not candidates:
|
|
117
|
+
raise RuntimeError(f"No deployed runtimes or harnesses found in target '{target_name}'.")
|
|
118
|
+
if len(candidates) > 1:
|
|
119
|
+
raise RuntimeError(
|
|
120
|
+
f"Target '{target_name}' has multiple deploy targets. Specify one with --runtime <name> or "
|
|
121
|
+
f"--harness <name>: " + ", ".join([*runtimes, *harnesses])
|
|
122
|
+
)
|
|
123
|
+
return _assert_interactive_harness_unsupported(options, ExecContext(region, candidates[0]))
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
# ---------------------------------------------------------------------------
|
|
127
|
+
# One-shot exec
|
|
128
|
+
# ---------------------------------------------------------------------------
|
|
129
|
+
|
|
130
|
+
_DONE = object()
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def _write(stream: Any, text: str) -> None:
|
|
134
|
+
stream.write(text)
|
|
135
|
+
stream.flush()
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def handle_exec_one_shot(ctx: ExecContext, options: ExecOptions) -> ExecResult:
|
|
139
|
+
command = " ".join(options.command or [])
|
|
140
|
+
if not command:
|
|
141
|
+
return ExecResult(False, error=RuntimeError("No command provided for one-shot exec."))
|
|
142
|
+
|
|
143
|
+
stdout_buf = ""
|
|
144
|
+
stderr_buf = ""
|
|
145
|
+
timeout_sec = options.timeout if options.timeout is not None and options.timeout > 0 else None
|
|
146
|
+
exit_code: int | None = None
|
|
147
|
+
timed_out = ExecResult(
|
|
148
|
+
False, error=RuntimeError(f"Command timed out after {timeout_sec}s"), session_id=options.session_id
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
try:
|
|
152
|
+
executed = execute_bash_command(
|
|
153
|
+
ExecuteBashOptions(
|
|
154
|
+
region=ctx.region,
|
|
155
|
+
runtime_arn=ctx.runtime_arn,
|
|
156
|
+
command=command,
|
|
157
|
+
session_id=options.session_id,
|
|
158
|
+
timeout=timeout_sec,
|
|
159
|
+
)
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
# Client-side wall-clock timeout: pull events on a worker thread and race against the deadline,
|
|
163
|
+
# so the timeout fires even when the stream is blocked with no events.
|
|
164
|
+
events: queue.Queue[Any] = queue.Queue()
|
|
165
|
+
|
|
166
|
+
def pump() -> None:
|
|
167
|
+
try:
|
|
168
|
+
for ev in executed.stream:
|
|
169
|
+
events.put(ev)
|
|
170
|
+
events.put(_DONE)
|
|
171
|
+
except BaseException as exc: # noqa: BLE001 - forwarded to the consumer
|
|
172
|
+
events.put(exc)
|
|
173
|
+
|
|
174
|
+
threading.Thread(target=pump, name="agentcore-exec-stream", daemon=True).start()
|
|
175
|
+
deadline = None
|
|
176
|
+
if timeout_sec is not None:
|
|
177
|
+
deadline = time.monotonic() + timeout_sec
|
|
178
|
+
|
|
179
|
+
while True:
|
|
180
|
+
if deadline is not None:
|
|
181
|
+
remaining = deadline - time.monotonic()
|
|
182
|
+
if remaining <= 0:
|
|
183
|
+
return timed_out
|
|
184
|
+
try:
|
|
185
|
+
event = events.get(timeout=remaining)
|
|
186
|
+
except queue.Empty:
|
|
187
|
+
return timed_out
|
|
188
|
+
else:
|
|
189
|
+
event = events.get()
|
|
190
|
+
if event is _DONE:
|
|
191
|
+
break
|
|
192
|
+
if isinstance(event, BaseException):
|
|
193
|
+
raise event
|
|
194
|
+
kind = event.get("type")
|
|
195
|
+
if kind == "stdout" and event.get("data"):
|
|
196
|
+
stdout_buf += event["data"]
|
|
197
|
+
if not options.json:
|
|
198
|
+
_write(sys.stdout, event["data"])
|
|
199
|
+
elif kind == "stderr" and event.get("data"):
|
|
200
|
+
stderr_buf += event["data"]
|
|
201
|
+
if not options.json:
|
|
202
|
+
_write(sys.stderr, event["data"])
|
|
203
|
+
elif kind == "stop":
|
|
204
|
+
exit_code = event.get("exitCode")
|
|
205
|
+
# Server-side timeout: status TIMED_OUT, or exit -1 when a timeout was set.
|
|
206
|
+
if event.get("status") == "TIMED_OUT" or (exit_code == -1 and timeout_sec is not None):
|
|
207
|
+
return timed_out
|
|
208
|
+
except Exception as exc: # noqa: BLE001
|
|
209
|
+
return ExecResult(False, error=exc)
|
|
210
|
+
|
|
211
|
+
if exit_code is None:
|
|
212
|
+
return ExecResult(False, error=RuntimeError("Command stream ended without exit code"))
|
|
213
|
+
if exit_code != 0:
|
|
214
|
+
return ExecResult(
|
|
215
|
+
False,
|
|
216
|
+
error=RuntimeError(f"Command exited with code {exit_code}"),
|
|
217
|
+
exit_code=exit_code,
|
|
218
|
+
stdout=stdout_buf,
|
|
219
|
+
stderr=stderr_buf,
|
|
220
|
+
session_id=options.session_id,
|
|
221
|
+
)
|
|
222
|
+
return ExecResult(True, exit_code=exit_code, stdout=stdout_buf, stderr=stderr_buf, session_id=options.session_id)
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
# ---------------------------------------------------------------------------
|
|
226
|
+
# Interactive PTY session
|
|
227
|
+
# ---------------------------------------------------------------------------
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
class _RawTerminal:
|
|
231
|
+
"""Put stdin into raw mode (keystrokes forwarded byte-for-byte) and restore it afterwards."""
|
|
232
|
+
|
|
233
|
+
def __init__(self) -> None:
|
|
234
|
+
self._saved: Any = None
|
|
235
|
+
self.fd: int | None = None
|
|
236
|
+
try:
|
|
237
|
+
self.fd = sys.stdin.fileno()
|
|
238
|
+
except (AttributeError, ValueError, OSError):
|
|
239
|
+
self.fd = None
|
|
240
|
+
|
|
241
|
+
def __enter__(self) -> "_RawTerminal":
|
|
242
|
+
if self.fd is not None and os.isatty(self.fd):
|
|
243
|
+
import termios
|
|
244
|
+
import tty
|
|
245
|
+
|
|
246
|
+
self._saved = termios.tcgetattr(self.fd)
|
|
247
|
+
tty.setraw(self.fd)
|
|
248
|
+
return self
|
|
249
|
+
|
|
250
|
+
def __exit__(self, *exc: object) -> None:
|
|
251
|
+
if self._saved is not None and self.fd is not None:
|
|
252
|
+
import termios
|
|
253
|
+
|
|
254
|
+
termios.tcsetattr(self.fd, termios.TCSADRAIN, self._saved)
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
def _close_code(ws: Any) -> int | None:
|
|
258
|
+
code = getattr(ws, "close_code", None)
|
|
259
|
+
if code is None:
|
|
260
|
+
protocol = getattr(ws, "protocol", None)
|
|
261
|
+
code = getattr(protocol, "close_code", None)
|
|
262
|
+
return code
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
def handle_shell_session(ctx: ExecContext, options: ExecOptions) -> ExecResult:
|
|
266
|
+
"""Open an interactive PTY shell against a running runtime container."""
|
|
267
|
+
session_id = options.session_id or str(uuid.uuid4())
|
|
268
|
+
_write(sys.stderr, "Connecting to agent VM...\n")
|
|
269
|
+
|
|
270
|
+
state = {"reconnect_attempts": 0, "was_kicked": False}
|
|
271
|
+
|
|
272
|
+
def on_attempt(attempt: int, reason: str) -> None:
|
|
273
|
+
state["reconnect_attempts"] = attempt
|
|
274
|
+
_write(sys.stderr, f"\r\n[disconnected · {reason} · reconnecting ({attempt}/5)...]\r\n")
|
|
275
|
+
|
|
276
|
+
def on_kicked() -> None:
|
|
277
|
+
state["was_kicked"] = True
|
|
278
|
+
_write(sys.stderr, "\r\n[session attached from another client · not reconnecting]\r\n")
|
|
279
|
+
|
|
280
|
+
try:
|
|
281
|
+
conn = connect_shell(
|
|
282
|
+
region=ctx.region,
|
|
283
|
+
runtime_arn=ctx.runtime_arn,
|
|
284
|
+
session_id=session_id,
|
|
285
|
+
shell_id=options.shell_id,
|
|
286
|
+
bearer_token=options.bearer_token,
|
|
287
|
+
headers={"baggage": options.baggage} if options.baggage else None,
|
|
288
|
+
reconnect=ShellReconnectOptions(on_attempt=on_attempt, on_kicked=on_kicked),
|
|
289
|
+
)
|
|
290
|
+
except Exception as exc: # noqa: BLE001
|
|
291
|
+
return ExecResult(False, error=exc)
|
|
292
|
+
|
|
293
|
+
framer = ShellFramer()
|
|
294
|
+
ws, shell_id = conn.ws, conn.shell_id
|
|
295
|
+
exit_code: int | None = None
|
|
296
|
+
detached = threading.Event()
|
|
297
|
+
stop_reading = threading.Event()
|
|
298
|
+
errored: list[BaseException] = []
|
|
299
|
+
|
|
300
|
+
_write(sys.stderr, f"[connected · session {session_id} · Ctrl+D or 'exit' to quit · Ctrl+] to detach]\n")
|
|
301
|
+
|
|
302
|
+
def terminate() -> None:
|
|
303
|
+
try:
|
|
304
|
+
ws.close(code=4001)
|
|
305
|
+
except Exception: # noqa: BLE001, S110
|
|
306
|
+
pass
|
|
307
|
+
|
|
308
|
+
stop_keepalive = start_keepalive(ws, terminate)
|
|
309
|
+
|
|
310
|
+
def send_resize(*_: object) -> None:
|
|
311
|
+
size = shutil.get_terminal_size((80, 24))
|
|
312
|
+
try:
|
|
313
|
+
ws.send(framer.encode_resize(size.columns, size.lines))
|
|
314
|
+
except Exception: # noqa: BLE001, S110 - socket not open
|
|
315
|
+
pass
|
|
316
|
+
|
|
317
|
+
def stdin_loop(fd: int) -> None:
|
|
318
|
+
while not stop_reading.is_set():
|
|
319
|
+
try:
|
|
320
|
+
ready, _, _ = select.select([fd], [], [], 0.1)
|
|
321
|
+
except (OSError, ValueError):
|
|
322
|
+
return
|
|
323
|
+
if not ready:
|
|
324
|
+
continue
|
|
325
|
+
try:
|
|
326
|
+
buf = os.read(fd, 4096)
|
|
327
|
+
except OSError:
|
|
328
|
+
return
|
|
329
|
+
if not buf:
|
|
330
|
+
return
|
|
331
|
+
if buf == b"\x1d": # Ctrl+] detaches without killing the remote shell
|
|
332
|
+
detached.set()
|
|
333
|
+
_write(sys.stderr, "\n[detached]\n")
|
|
334
|
+
try:
|
|
335
|
+
ws.close()
|
|
336
|
+
except Exception: # noqa: BLE001, S110
|
|
337
|
+
pass
|
|
338
|
+
return
|
|
339
|
+
try:
|
|
340
|
+
ws.send(framer.encode_stdin_raw(buf))
|
|
341
|
+
except Exception: # noqa: BLE001
|
|
342
|
+
return
|
|
343
|
+
|
|
344
|
+
previous_winch = None
|
|
345
|
+
with _RawTerminal() as term:
|
|
346
|
+
if hasattr(signal, "SIGWINCH") and threading.current_thread() is threading.main_thread():
|
|
347
|
+
previous_winch = signal.signal(signal.SIGWINCH, send_resize)
|
|
348
|
+
send_resize()
|
|
349
|
+
reader = None
|
|
350
|
+
if term.fd is not None:
|
|
351
|
+
reader = threading.Thread(target=stdin_loop, args=(term.fd,), name="agentcore-shell-stdin", daemon=True)
|
|
352
|
+
reader.start()
|
|
353
|
+
try:
|
|
354
|
+
while True:
|
|
355
|
+
try:
|
|
356
|
+
data = ws.recv()
|
|
357
|
+
except Exception as exc: # noqa: BLE001 - ConnectionClosed ends the loop
|
|
358
|
+
if type(exc).__name__ not in ("ConnectionClosedOK", "ConnectionClosedError", "ConnectionClosed"):
|
|
359
|
+
errored.append(exc)
|
|
360
|
+
break
|
|
361
|
+
raw = data if isinstance(data, (bytes, bytearray)) else str(data).encode("utf-8")
|
|
362
|
+
try:
|
|
363
|
+
frame = framer.decode(bytes(raw))
|
|
364
|
+
except ValueError:
|
|
365
|
+
continue
|
|
366
|
+
if frame.channel == ShellChannel.STDOUT:
|
|
367
|
+
sys.stdout.buffer.write(frame.payload)
|
|
368
|
+
sys.stdout.buffer.flush()
|
|
369
|
+
elif frame.channel == ShellChannel.STDERR:
|
|
370
|
+
sys.stderr.buffer.write(frame.payload)
|
|
371
|
+
sys.stderr.buffer.flush()
|
|
372
|
+
elif frame.channel == ShellChannel.STATUS:
|
|
373
|
+
parsed = parse_status_frame(frame)
|
|
374
|
+
if parsed["type"] == "termination":
|
|
375
|
+
exit_code = parsed["exitCode"]
|
|
376
|
+
ws.close()
|
|
377
|
+
elif frame.channel == ShellChannel.CLOSE:
|
|
378
|
+
ws.close()
|
|
379
|
+
finally:
|
|
380
|
+
stop_reading.set()
|
|
381
|
+
if reader is not None:
|
|
382
|
+
reader.join(timeout=1)
|
|
383
|
+
stop_keepalive()
|
|
384
|
+
if previous_winch is not None:
|
|
385
|
+
signal.signal(signal.SIGWINCH, previous_winch)
|
|
386
|
+
|
|
387
|
+
transport_failure = False
|
|
388
|
+
if errored:
|
|
389
|
+
_write(sys.stderr, f"\n[shell error: {errored[0]}]\n")
|
|
390
|
+
code: int | None = exit_code if exit_code is not None else 1
|
|
391
|
+
elif exit_code is not None:
|
|
392
|
+
code = exit_code
|
|
393
|
+
else:
|
|
394
|
+
close = _close_code(ws)
|
|
395
|
+
if close == 1000 or (close is None and detached.is_set()):
|
|
396
|
+
code = 0
|
|
397
|
+
elif close == 4000:
|
|
398
|
+
code = None
|
|
399
|
+
else:
|
|
400
|
+
code = None
|
|
401
|
+
transport_failure = True
|
|
402
|
+
|
|
403
|
+
is_detached = detached.is_set()
|
|
404
|
+
if shell_id and (is_detached or code is None):
|
|
405
|
+
if not is_detached:
|
|
406
|
+
_write(sys.stderr, "\n[disconnected]\n")
|
|
407
|
+
_write(
|
|
408
|
+
sys.stderr,
|
|
409
|
+
"[to reconnect:]\n"
|
|
410
|
+
" agentcore exec --it \\\n"
|
|
411
|
+
f" --runtime {ctx.runtime_arn} \\\n"
|
|
412
|
+
f" --region {ctx.region} \\\n"
|
|
413
|
+
f" --session-id {session_id} \\\n"
|
|
414
|
+
f" --shell-id {shell_id}\n",
|
|
415
|
+
)
|
|
416
|
+
if code is not None and not is_detached:
|
|
417
|
+
_write(sys.stderr, f"\n[session closed · exit {code}]\n")
|
|
418
|
+
|
|
419
|
+
meta: dict[str, Any] = {
|
|
420
|
+
"session_id": session_id,
|
|
421
|
+
"shell_id": shell_id,
|
|
422
|
+
"exit_code": code,
|
|
423
|
+
"reconnect_attempts": state["reconnect_attempts"],
|
|
424
|
+
"was_kicked": state["was_kicked"],
|
|
425
|
+
"detached": is_detached,
|
|
426
|
+
}
|
|
427
|
+
if transport_failure:
|
|
428
|
+
return ExecResult(
|
|
429
|
+
False,
|
|
430
|
+
error=RuntimeError("Shell connection closed unexpectedly before the shell reported an exit status"),
|
|
431
|
+
**meta,
|
|
432
|
+
)
|
|
433
|
+
if code is None or code == 0 or code >= 128:
|
|
434
|
+
return ExecResult(True, **meta)
|
|
435
|
+
return ExecResult(False, error=RuntimeError(f"Shell exited with code {code}"), **meta)
|
|
436
|
+
|
|
437
|
+
|
|
438
|
+
def run_interactive_shell(options: ExecOptions) -> None:
|
|
439
|
+
ctx = load_exec_context(options)
|
|
440
|
+
res = handle_shell_session(ctx, options)
|
|
441
|
+
if not res.success:
|
|
442
|
+
raise res.error or RuntimeError("exec failed")
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
"""`agentcore exec` (port of commands/exec/command.tsx)."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import sys
|
|
5
|
+
from dataclasses import dataclass, replace
|
|
6
|
+
|
|
7
|
+
import typer
|
|
8
|
+
|
|
9
|
+
from agentcore.cli import interactive
|
|
10
|
+
from agentcore.cli.commands.exec.action import (
|
|
11
|
+
handle_exec_one_shot,
|
|
12
|
+
handle_shell_session,
|
|
13
|
+
load_exec_context,
|
|
14
|
+
run_interactive_shell,
|
|
15
|
+
)
|
|
16
|
+
from agentcore.cli.commands.exec.types import ExecOptions, ExecResult
|
|
17
|
+
from agentcore.cli.commands.invoke.constants import ANSI, EXEC_DESCRIPTION
|
|
18
|
+
from agentcore.cli.commands.invoke.guards import require_project
|
|
19
|
+
from agentcore.cli.errors import get_error_message
|
|
20
|
+
from agentcore.lib.schemas.io.config_io import ConfigIO
|
|
21
|
+
from agentcore.lib.schemas.io.path_resolver import find_config_root
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _print_exec_result(res: ExecResult, as_json: bool) -> None:
|
|
25
|
+
if as_json:
|
|
26
|
+
payload = {
|
|
27
|
+
"success": res.success,
|
|
28
|
+
"exitCode": res.exit_code,
|
|
29
|
+
"stdout": res.stdout or "",
|
|
30
|
+
"stderr": res.stderr or "",
|
|
31
|
+
}
|
|
32
|
+
typer.echo(
|
|
33
|
+
json.dumps({k: v for k, v in payload.items() if v is not None}, separators=(",", ":"), ensure_ascii=False)
|
|
34
|
+
)
|
|
35
|
+
elif not res.success and res.error is not None:
|
|
36
|
+
typer.echo(f"Error: {res.error}", err=True)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@dataclass
|
|
40
|
+
class PickResult:
|
|
41
|
+
runtime_arn: str
|
|
42
|
+
session_id: str | None = None
|
|
43
|
+
auto_selected: bool = False
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def pick_agent() -> PickResult | None:
|
|
47
|
+
"""Prompt replacement for the ExecScreen picker. Returns None when the user backs out."""
|
|
48
|
+
try:
|
|
49
|
+
config_io = ConfigIO()
|
|
50
|
+
project = config_io.read_project_spec()
|
|
51
|
+
deployed_state = config_io.read_deployed_state()
|
|
52
|
+
target_names = list(deployed_state.targets or {})
|
|
53
|
+
if not target_names:
|
|
54
|
+
raise RuntimeError("No deployed targets found. Run `agentcore deploy` first.")
|
|
55
|
+
target_state = deployed_state.targets[target_names[0]]
|
|
56
|
+
resources = target_state.resources if target_state else None
|
|
57
|
+
loaded: list[interactive.Choice] = []
|
|
58
|
+
for agent in project.runtimes or []:
|
|
59
|
+
state = ((resources.runtimes if resources else None) or {}).get(agent.name)
|
|
60
|
+
if state and state.runtime_arn:
|
|
61
|
+
loaded.append(interactive.Choice(agent.name, state.runtime_arn))
|
|
62
|
+
# exec targets the harness ARN (not agentRuntimeArn) for harnesses.
|
|
63
|
+
for harness in project.harnesses or []:
|
|
64
|
+
state = ((resources.harnesses if resources else None) or {}).get(harness.name)
|
|
65
|
+
if state and state.harness_arn:
|
|
66
|
+
loaded.append(interactive.Choice(harness.name, state.harness_arn, "harness"))
|
|
67
|
+
if not loaded:
|
|
68
|
+
raise RuntimeError("No deployed agents or harnesses found. Run `agentcore deploy` first.")
|
|
69
|
+
except Exception as exc: # noqa: BLE001 - shown as the picker's error state upstream
|
|
70
|
+
typer.echo(f"{ANSI.red}{get_error_message(exc)}{ANSI.reset}")
|
|
71
|
+
return None
|
|
72
|
+
|
|
73
|
+
if len(loaded) == 1:
|
|
74
|
+
return PickResult(loaded[0].value, auto_selected=True)
|
|
75
|
+
try:
|
|
76
|
+
arn = interactive.select("Select Agent to Shell Into", loaded)
|
|
77
|
+
except typer.Exit:
|
|
78
|
+
return None
|
|
79
|
+
return PickResult(arn)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def run_exec_loop(options: ExecOptions | None = None) -> None:
|
|
83
|
+
"""Picker loop: pick agent -> PTY -> back to the picker (or quit)."""
|
|
84
|
+
options = options or ExecOptions()
|
|
85
|
+
while True:
|
|
86
|
+
picked = pick_agent()
|
|
87
|
+
if picked is None:
|
|
88
|
+
break
|
|
89
|
+
shell_options = replace(options, interactive=True, runtime_arn=picked.runtime_arn, session_id=picked.session_id)
|
|
90
|
+
session_error: BaseException | None = None
|
|
91
|
+
try:
|
|
92
|
+
ctx = load_exec_context(shell_options)
|
|
93
|
+
res = handle_shell_session(ctx, shell_options)
|
|
94
|
+
if not res.success and res.error is not None:
|
|
95
|
+
session_error = res.error
|
|
96
|
+
except Exception as exc: # noqa: BLE001
|
|
97
|
+
session_error = exc
|
|
98
|
+
if picked.auto_selected:
|
|
99
|
+
if session_error is not None:
|
|
100
|
+
raise session_error
|
|
101
|
+
break
|
|
102
|
+
sys.stdout.write("\x1b[2J\x1b[H")
|
|
103
|
+
sys.stdout.flush()
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def exec_command(
|
|
107
|
+
command_args: list[str] | None = typer.Argument(
|
|
108
|
+
None, metavar="[COMMAND...]", help="Command to execute (one-shot mode, non-interactive)", show_default=False
|
|
109
|
+
),
|
|
110
|
+
it: bool = typer.Option(False, "--it", help="Open an interactive PTY shell session"),
|
|
111
|
+
runtime: str | None = typer.Option(
|
|
112
|
+
None, "--runtime", metavar="NAME|ARN", help="Target agent name or runtime ARN (skips agent picker)"
|
|
113
|
+
),
|
|
114
|
+
harness: str | None = typer.Option(
|
|
115
|
+
None, "--harness", metavar="NAME|ARN", help="Target harness name or harness ARN (skips agent picker)"
|
|
116
|
+
),
|
|
117
|
+
session_id: str | None = typer.Option(None, "--session-id", help="Pin to a specific runtime session / VM"),
|
|
118
|
+
shell_id: str | None = typer.Option(None, "--shell-id", help="Reconnect to an existing shell"),
|
|
119
|
+
region: str | None = typer.Option(None, "--region", help="AWS region"),
|
|
120
|
+
bearer_token: str | None = typer.Option(
|
|
121
|
+
None, "--bearer-token", help="Bearer token for CUSTOM_JWT authentication (skips SigV4)"
|
|
122
|
+
),
|
|
123
|
+
target: str | None = typer.Option(None, "--target", help="Deployment target name (from agentcore.json)"),
|
|
124
|
+
timeout: int | None = typer.Option(None, "--timeout", help="Timeout in seconds for one-shot commands"),
|
|
125
|
+
as_json: bool = typer.Option(
|
|
126
|
+
False, "--json", help="Output result as JSON (one-shot mode only, incompatible with --it)"
|
|
127
|
+
),
|
|
128
|
+
) -> None:
|
|
129
|
+
try:
|
|
130
|
+
# A full ARN needs no project; a name-based --runtime/--harness still does.
|
|
131
|
+
has_arn_target = bool(runtime and runtime.startswith("arn:")) or bool(harness and harness.startswith("arn:"))
|
|
132
|
+
if not has_arn_target:
|
|
133
|
+
if as_json:
|
|
134
|
+
if not find_config_root():
|
|
135
|
+
typer.echo(
|
|
136
|
+
json.dumps({"success": False, "error": "No agentcore project found."}, separators=(",", ":"))
|
|
137
|
+
)
|
|
138
|
+
raise typer.Exit(1)
|
|
139
|
+
else:
|
|
140
|
+
require_project()
|
|
141
|
+
|
|
142
|
+
if it and as_json:
|
|
143
|
+
typer.echo("Error: --json cannot be used with --it (PTY sessions are not JSON-serializable)", err=True)
|
|
144
|
+
raise typer.Exit(1)
|
|
145
|
+
if it and timeout is not None:
|
|
146
|
+
typer.echo("Error: --timeout cannot be used with --it (timeouts apply to one-shot commands only)", err=True)
|
|
147
|
+
raise typer.Exit(1)
|
|
148
|
+
if not it and bearer_token:
|
|
149
|
+
typer.echo(
|
|
150
|
+
"Error: --bearer-token is only supported with --it (bearer token auth is not supported for one-shot "
|
|
151
|
+
"commands)",
|
|
152
|
+
err=True,
|
|
153
|
+
)
|
|
154
|
+
raise typer.Exit(1)
|
|
155
|
+
if timeout is not None and timeout < 0:
|
|
156
|
+
typer.echo("Error: --timeout must be a non-negative integer (seconds)", err=True)
|
|
157
|
+
raise typer.Exit(1)
|
|
158
|
+
if session_id is not None and (len(session_id) < 33 or len(session_id) > 256):
|
|
159
|
+
typer.echo("Error: --session-id must be between 33 and 256 characters", err=True)
|
|
160
|
+
raise typer.Exit(1)
|
|
161
|
+
|
|
162
|
+
options = ExecOptions(
|
|
163
|
+
runtime_arn=runtime,
|
|
164
|
+
harness_name=harness,
|
|
165
|
+
session_id=session_id,
|
|
166
|
+
shell_id=shell_id,
|
|
167
|
+
interactive=it or None,
|
|
168
|
+
command=list(command_args) if command_args else None,
|
|
169
|
+
region=region,
|
|
170
|
+
bearer_token=bearer_token,
|
|
171
|
+
target_name=target,
|
|
172
|
+
timeout=timeout,
|
|
173
|
+
json=as_json or None,
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
if not options.interactive:
|
|
177
|
+
if not options.command:
|
|
178
|
+
typer.echo(
|
|
179
|
+
"Usage:\n agentcore exec <command> one-shot\n agentcore exec --it "
|
|
180
|
+
"interactive shell",
|
|
181
|
+
err=True,
|
|
182
|
+
)
|
|
183
|
+
raise typer.Exit(1)
|
|
184
|
+
ctx = load_exec_context(options)
|
|
185
|
+
res = handle_exec_one_shot(ctx, options)
|
|
186
|
+
_print_exec_result(res, as_json)
|
|
187
|
+
raise typer.Exit(res.exit_code if res.exit_code is not None else (0 if res.success else 1))
|
|
188
|
+
|
|
189
|
+
interactive.require_tty()
|
|
190
|
+
if options.runtime_arn or options.harness_name:
|
|
191
|
+
run_interactive_shell(options)
|
|
192
|
+
raise typer.Exit(0)
|
|
193
|
+
run_exec_loop(options)
|
|
194
|
+
raise typer.Exit(0)
|
|
195
|
+
except typer.Exit:
|
|
196
|
+
raise
|
|
197
|
+
except Exception as exc: # noqa: BLE001 - top-level command boundary, as upstream
|
|
198
|
+
if as_json:
|
|
199
|
+
typer.echo(json.dumps({"success": False, "error": get_error_message(exc)}, separators=(",", ":")))
|
|
200
|
+
else:
|
|
201
|
+
typer.echo(get_error_message(exc), err=True)
|
|
202
|
+
raise typer.Exit(1) from None
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def register_exec(app: typer.Typer) -> None:
|
|
206
|
+
app.command("exec", help=EXEC_DESCRIPTION)(exec_command)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""Port of commands/exec/types.ts."""
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@dataclass
|
|
7
|
+
class ExecOptions:
|
|
8
|
+
runtime_arn: str | None = None
|
|
9
|
+
"""--runtime: agent name or full runtime ARN. Skips the agent picker."""
|
|
10
|
+
harness_name: str | None = None
|
|
11
|
+
"""--harness: harness name or harness ARN. Skips the agent picker."""
|
|
12
|
+
session_id: str | None = None
|
|
13
|
+
shell_id: str | None = None
|
|
14
|
+
interactive: bool | None = None
|
|
15
|
+
command: list[str] | None = None
|
|
16
|
+
region: str | None = None
|
|
17
|
+
bearer_token: str | None = None
|
|
18
|
+
target_name: str | None = None
|
|
19
|
+
baggage: str | None = None
|
|
20
|
+
timeout: int | None = None
|
|
21
|
+
json: bool | None = None
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass
|
|
25
|
+
class ExecResult:
|
|
26
|
+
success: bool
|
|
27
|
+
error: Exception | None = None
|
|
28
|
+
session_id: str | None = None
|
|
29
|
+
shell_id: str | None = None
|
|
30
|
+
exit_code: int | None = None
|
|
31
|
+
reconnect_attempts: int | None = None
|
|
32
|
+
was_kicked: bool | None = None
|
|
33
|
+
detached: bool | None = None
|
|
34
|
+
stdout: str | None = None
|
|
35
|
+
stderr: str | None = None
|