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,808 @@
|
|
|
1
|
+
"""`agentcore run eval|batch-evaluation|insights|recommendation|ab-test` (port of commands/run/command.tsx).
|
|
2
|
+
|
|
3
|
+
`run ingest` belongs to the knowledge-base area (cli/commands/run_ingest.py).
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import json
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
import typer
|
|
10
|
+
|
|
11
|
+
from agentcore.cli.commands._jobs_common import fail_early, print_json, red, require_project
|
|
12
|
+
from agentcore.cli.errors import get_error_message
|
|
13
|
+
from agentcore.cli.groups import group
|
|
14
|
+
from agentcore.cli.run_command import run_cli_command
|
|
15
|
+
from agentcore.cli.variadic import variadic
|
|
16
|
+
from agentcore.lib import ConfigIO, ValidationError, serialize_result
|
|
17
|
+
from agentcore.operations.eval.run_eval import handle_run_eval
|
|
18
|
+
from agentcore.operations.jobs import create_job_engine, run_dataset_phase1, wait_for_terminal
|
|
19
|
+
from agentcore.operations.jobs.ab_test.format import print_ab_test_detail
|
|
20
|
+
from agentcore.operations.jobs.recommendation.format import failure_text
|
|
21
|
+
from agentcore.operations.jobs.shared.format import parse_int, to_fixed, to_locale_string
|
|
22
|
+
from agentcore.schema import is_valid_kms_key_arn
|
|
23
|
+
|
|
24
|
+
RECOMMENDATION_TYPE_MAP = {
|
|
25
|
+
"system-prompt": "SYSTEM_PROMPT_RECOMMENDATION",
|
|
26
|
+
"tool-description": "TOOL_DESCRIPTION_RECOMMENDATION",
|
|
27
|
+
}
|
|
28
|
+
_DATASET_VERSION_ERROR = "--dataset-version requires --dataset (the version selects a version of that dataset)"
|
|
29
|
+
_ENDPOINT_HELP = "Runtime endpoint name (e.g. PROMPT_V1). Defaults to AGENTCORE_RUNTIME_ENDPOINT env var, then DEFAULT"
|
|
30
|
+
_KMS_HELP_ERROR = (
|
|
31
|
+
"--kms-key must be a valid KMS key ARN "
|
|
32
|
+
"(e.g. arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012)"
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
run_app = group("run")
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _job_json(record: dict[str, Any], extra: dict[str, Any] | None = None) -> None:
|
|
39
|
+
print_json(serialize_result({"success": True, **record, **(extra or {})}))
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
# ──────────────────────────────────────────────────────────────────────────────
|
|
43
|
+
# run eval
|
|
44
|
+
# ──────────────────────────────────────────────────────────────────────────────
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def format_run_output(value: dict[str, Any]) -> None:
|
|
48
|
+
run = value["run"]
|
|
49
|
+
lookback = "" if run.get("source") == "dataset" else f" | Lookback: {run.get('lookbackDays')}d"
|
|
50
|
+
dataset = run.get("dataset")
|
|
51
|
+
dataset_str = (
|
|
52
|
+
f" | Dataset: {dataset['id']}@{dataset['version']}" if run.get("source") == "dataset" and dataset else ""
|
|
53
|
+
)
|
|
54
|
+
typer.echo(
|
|
55
|
+
f"\nAgent: {run['agent']} | {to_locale_string(run['timestamp'])} | Sessions: {run['sessionCount']}"
|
|
56
|
+
f"{lookback}{dataset_str}"
|
|
57
|
+
)
|
|
58
|
+
refs = run.get("referenceInputs")
|
|
59
|
+
if refs:
|
|
60
|
+
parts = []
|
|
61
|
+
if refs.get("assertions"):
|
|
62
|
+
parts.append(f"{len(refs['assertions'])} assertion(s)")
|
|
63
|
+
if refs.get("expectedResponse"):
|
|
64
|
+
parts.append("expected response")
|
|
65
|
+
if refs.get("expectedTrajectory"):
|
|
66
|
+
parts.append(f"{len(refs['expectedTrajectory'])} trajectory step(s)")
|
|
67
|
+
if parts:
|
|
68
|
+
typer.echo(f"Reference inputs: {', '.join(parts)}")
|
|
69
|
+
typer.echo("")
|
|
70
|
+
for r in run["results"]:
|
|
71
|
+
errors = sum(1 for s in r["sessionScores"] if s.get("errorMessage"))
|
|
72
|
+
suffix = f" ({errors} errors)" if errors else ""
|
|
73
|
+
typer.echo(f" {r['evaluator']}: {to_fixed(r['aggregateScore'], 2)}{suffix}")
|
|
74
|
+
if value.get("filePath"):
|
|
75
|
+
typer.echo(f"\nResults saved to: {value['filePath']}")
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@run_app.command(
|
|
79
|
+
"eval",
|
|
80
|
+
help="Run on-demand evaluation of runtime traces. Use --runtime-arn to evaluate runtimes outside the project.",
|
|
81
|
+
cls=variadic("-e", "--evaluator", "--evaluator-arn", "-A", "--assertion"),
|
|
82
|
+
)
|
|
83
|
+
def run_eval(
|
|
84
|
+
runtime: str | None = typer.Option(None, "-r", "--runtime", help="Runtime name from project config"),
|
|
85
|
+
runtime_arn: str | None = typer.Option(None, "--runtime-arn", help="Runtime ARN — run outside a project directory"),
|
|
86
|
+
evaluator: list[str] | None = typer.Option(
|
|
87
|
+
None, "-e", "--evaluator", help="Evaluator name(s) — project evaluators or Builtin.* IDs"
|
|
88
|
+
),
|
|
89
|
+
evaluator_arn: list[str] | None = typer.Option(
|
|
90
|
+
None, "--evaluator-arn", help="Evaluator ARN(s) — use with --runtime-arn for standalone mode"
|
|
91
|
+
),
|
|
92
|
+
region: str | None = typer.Option(
|
|
93
|
+
None, "--region", help="AWS region (required with --runtime-arn, auto-detected otherwise)"
|
|
94
|
+
),
|
|
95
|
+
session_id: str | None = typer.Option(None, "-s", "--session-id", help="Evaluate a specific session only"),
|
|
96
|
+
trace_id: str | None = typer.Option(None, "-t", "--trace-id", help="Evaluate a specific trace only"),
|
|
97
|
+
endpoint: str | None = typer.Option(None, "--endpoint", help=_ENDPOINT_HELP),
|
|
98
|
+
days: str = typer.Option("7", "--days", help="Lookback window in days"),
|
|
99
|
+
assertion: list[str] | None = typer.Option(
|
|
100
|
+
None, "-A", "--assertion", help="Ground truth assertion the agent response must satisfy (repeatable)"
|
|
101
|
+
),
|
|
102
|
+
expected_trajectory: str | None = typer.Option(
|
|
103
|
+
None, "--expected-trajectory", help="Ground truth: expected tool call names in order (comma-separated)"
|
|
104
|
+
),
|
|
105
|
+
expected_response: str | None = typer.Option(
|
|
106
|
+
None, "--expected-response", help="Ground truth: expected agent response text to compare against"
|
|
107
|
+
),
|
|
108
|
+
output: str | None = typer.Option(None, "--output", help="Custom output file path for results"),
|
|
109
|
+
dataset: str | None = typer.Option(
|
|
110
|
+
None, "--dataset", help="Dataset name — invoke agent with dataset scenarios instead of historical traces"
|
|
111
|
+
),
|
|
112
|
+
dataset_version: str | None = typer.Option(
|
|
113
|
+
None, "--dataset-version", help="Dataset version to use (omit for local file, or N/DRAFT)"
|
|
114
|
+
),
|
|
115
|
+
as_json: bool = typer.Option(False, "--json", help="Output as JSON"),
|
|
116
|
+
) -> None:
|
|
117
|
+
if not (runtime_arn and evaluator_arn):
|
|
118
|
+
require_project()
|
|
119
|
+
if not evaluator and not evaluator_arn:
|
|
120
|
+
fail_early(as_json, "At least one --evaluator or --evaluator-arn is required")
|
|
121
|
+
if dataset_version and not dataset:
|
|
122
|
+
fail_early(as_json, _DATASET_VERSION_ERROR)
|
|
123
|
+
|
|
124
|
+
options = {
|
|
125
|
+
"agent": runtime,
|
|
126
|
+
"agentArn": runtime_arn,
|
|
127
|
+
"evaluator": evaluator or [],
|
|
128
|
+
"evaluatorArn": evaluator_arn or None,
|
|
129
|
+
"region": region,
|
|
130
|
+
"sessionId": session_id,
|
|
131
|
+
"traceId": trace_id,
|
|
132
|
+
"endpoint": endpoint,
|
|
133
|
+
"assertions": assertion or None,
|
|
134
|
+
"expectedTrajectory": [s.strip() for s in expected_trajectory.split(",")] if expected_trajectory else None,
|
|
135
|
+
"expectedResponse": expected_response,
|
|
136
|
+
"days": parse_int(days),
|
|
137
|
+
"output": output,
|
|
138
|
+
"dataset": dataset,
|
|
139
|
+
"datasetVersion": dataset_version,
|
|
140
|
+
"onProgress": None if as_json else (lambda _phase, message: typer.echo(message)),
|
|
141
|
+
}
|
|
142
|
+
try:
|
|
143
|
+
result = handle_run_eval(options)
|
|
144
|
+
if as_json:
|
|
145
|
+
print_json(serialize_result(result))
|
|
146
|
+
elif result.success:
|
|
147
|
+
format_run_output(result.value)
|
|
148
|
+
else:
|
|
149
|
+
red(str(result.error))
|
|
150
|
+
raise typer.Exit(0 if result.success else 1)
|
|
151
|
+
except typer.Exit:
|
|
152
|
+
raise
|
|
153
|
+
except Exception as exc: # noqa: BLE001
|
|
154
|
+
if as_json:
|
|
155
|
+
print_json({"success": False, "error": get_error_message(exc)})
|
|
156
|
+
else:
|
|
157
|
+
red(f"Error: {get_error_message(exc)}")
|
|
158
|
+
raise typer.Exit(1) from None
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
# ──────────────────────────────────────────────────────────────────────────────
|
|
162
|
+
# run batch-evaluation
|
|
163
|
+
# ──────────────────────────────────────────────────────────────────────────────
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def print_batch_eval_result(record: dict[str, Any]) -> None:
|
|
167
|
+
results = record.get("evaluationResults")
|
|
168
|
+
if results:
|
|
169
|
+
parts = []
|
|
170
|
+
if results.get("totalNumberOfSessions") is not None:
|
|
171
|
+
parts.append(f"{results['totalNumberOfSessions']} sessions")
|
|
172
|
+
if results.get("numberOfSessionsCompleted") is not None:
|
|
173
|
+
parts.append(f"{results['numberOfSessionsCompleted']} completed")
|
|
174
|
+
if results.get("numberOfSessionsFailed"):
|
|
175
|
+
parts.append(f"{results['numberOfSessionsFailed']} failed")
|
|
176
|
+
if parts:
|
|
177
|
+
typer.echo(f"Sessions: {', '.join(parts)}")
|
|
178
|
+
summaries = (results or {}).get("evaluatorSummaries")
|
|
179
|
+
if summaries:
|
|
180
|
+
typer.echo("\nResults:")
|
|
181
|
+
for s in summaries:
|
|
182
|
+
avg = (s.get("statistics") or {}).get("averageScore")
|
|
183
|
+
fail = f" ({s['totalFailed']} failed)" if s.get("totalFailed") else ""
|
|
184
|
+
count = f" [{s['totalEvaluated']} evaluated]" if s.get("totalEvaluated") is not None else ""
|
|
185
|
+
typer.echo(f" {s.get('evaluatorId')}: {to_fixed(avg, 2) if avg is not None else 'N/A'} avg{fail}{count}")
|
|
186
|
+
elif record.get("results"):
|
|
187
|
+
typer.echo("\nResults:")
|
|
188
|
+
groups: dict[str, list[dict[str, Any]]] = {}
|
|
189
|
+
for r in record["results"]:
|
|
190
|
+
groups.setdefault(r.get("evaluatorId"), []).append(r)
|
|
191
|
+
for evaluator_id, entries in groups.items():
|
|
192
|
+
scores = [r["score"] for r in entries if not r.get("error") and r.get("score") is not None]
|
|
193
|
+
avg = sum(scores) / len(scores) if scores else 0
|
|
194
|
+
errors = sum(1 for r in entries if r.get("error"))
|
|
195
|
+
typer.echo(f" {evaluator_id}: {to_fixed(avg, 2)} avg{f' ({errors} errors)' if errors else ''}")
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
@run_app.command(
|
|
199
|
+
"batch-evaluation",
|
|
200
|
+
help="Run evaluators in batch across all agent sessions in CloudWatch",
|
|
201
|
+
cls=variadic("-e", "--evaluator", "--evaluator-arn", "-s", "--session-ids"),
|
|
202
|
+
)
|
|
203
|
+
def run_batch_evaluation(
|
|
204
|
+
runtime: str | None = typer.Option(
|
|
205
|
+
None, "-r", "--runtime", help="Runtime name from project config [non-interactive]"
|
|
206
|
+
),
|
|
207
|
+
evaluator: list[str] | None = typer.Option(
|
|
208
|
+
None, "-e", "--evaluator", help="Evaluator name(s) — Builtin.* IDs [non-interactive]"
|
|
209
|
+
),
|
|
210
|
+
evaluator_arn: list[str] | None = typer.Option(
|
|
211
|
+
None, "--evaluator-arn", help="Evaluator ARN(s) — use instead of -e when referencing evaluators by ARN"
|
|
212
|
+
),
|
|
213
|
+
name: str | None = typer.Option(
|
|
214
|
+
None, "-n", "--name", help="Name for the batch evaluation (auto-generated if omitted)"
|
|
215
|
+
),
|
|
216
|
+
lookback_days: str | None = typer.Option(
|
|
217
|
+
None, "-d", "--lookback-days", help="Lookback window in days (filters sessions by time range)"
|
|
218
|
+
),
|
|
219
|
+
session_ids: list[str] | None = typer.Option(None, "-s", "--session-ids", help="Specific session IDs to evaluate"),
|
|
220
|
+
ground_truth: str | None = typer.Option(
|
|
221
|
+
None,
|
|
222
|
+
"-g",
|
|
223
|
+
"--ground-truth",
|
|
224
|
+
help="JSON file with session metadata and ground truth (assertions, expected trajectory, turns)",
|
|
225
|
+
),
|
|
226
|
+
region: str | None = typer.Option(None, "--region", help="AWS region (auto-detected if omitted)"),
|
|
227
|
+
endpoint: str | None = typer.Option(None, "--endpoint", help=_ENDPOINT_HELP),
|
|
228
|
+
dataset: str | None = typer.Option(
|
|
229
|
+
None, "--dataset", help="Dataset name — invoke agent with dataset scenarios before batch evaluation"
|
|
230
|
+
),
|
|
231
|
+
dataset_version: str | None = typer.Option(
|
|
232
|
+
None, "--dataset-version", help="Dataset version to use (omit for local file, or N/DRAFT)"
|
|
233
|
+
),
|
|
234
|
+
kms_key: str | None = typer.Option(None, "--kms-key", help="KMS key ARN for encrypting batch evaluation results"),
|
|
235
|
+
wait: bool = typer.Option(False, "--wait", help="Block until the batch evaluation reaches a terminal state"),
|
|
236
|
+
as_json: bool = typer.Option(False, "--json", help="Output as JSON"),
|
|
237
|
+
) -> None:
|
|
238
|
+
require_project()
|
|
239
|
+
if not runtime and not as_json:
|
|
240
|
+
from agentcore.cli import interactive
|
|
241
|
+
from agentcore.cli.commands._run_wizards import run_batch_eval_wizard
|
|
242
|
+
|
|
243
|
+
interactive.require_tty()
|
|
244
|
+
run_batch_eval_wizard()
|
|
245
|
+
raise typer.Exit(0)
|
|
246
|
+
if not runtime or (not evaluator and not evaluator_arn):
|
|
247
|
+
fail_early(
|
|
248
|
+
as_json, "--runtime and at least one --evaluator or --evaluator-arn are required in non-interactive mode"
|
|
249
|
+
)
|
|
250
|
+
if dataset_version and not dataset:
|
|
251
|
+
fail_early(as_json, _DATASET_VERSION_ERROR)
|
|
252
|
+
|
|
253
|
+
def log(message: str) -> None:
|
|
254
|
+
if not as_json:
|
|
255
|
+
typer.echo(message)
|
|
256
|
+
|
|
257
|
+
def run() -> None:
|
|
258
|
+
engine = create_job_engine(ConfigIO())
|
|
259
|
+
session_metadata = None
|
|
260
|
+
if ground_truth:
|
|
261
|
+
with open(ground_truth, encoding="utf-8") as fh:
|
|
262
|
+
data = json.load(fh)
|
|
263
|
+
parsed = (
|
|
264
|
+
data if isinstance(data, list) else (data.get("sessionMetadata") if isinstance(data, dict) else None)
|
|
265
|
+
)
|
|
266
|
+
if not isinstance(parsed, list):
|
|
267
|
+
raise Exception(
|
|
268
|
+
"Ground truth file must be a JSON array of session metadata entries, or an object with a "
|
|
269
|
+
'"sessionMetadata" key'
|
|
270
|
+
)
|
|
271
|
+
session_metadata = parsed
|
|
272
|
+
days = parse_int(lookback_days) if lookback_days else None
|
|
273
|
+
if lookback_days and (days is None or days < 1 or days > 90):
|
|
274
|
+
raise Exception("--lookback-days must be between 1 and 90")
|
|
275
|
+
ids = list(session_ids) if session_ids else None
|
|
276
|
+
dataset_info = {"id": dataset, "version": dataset_version or "LOCAL"} if dataset else None
|
|
277
|
+
if dataset:
|
|
278
|
+
phase1 = run_dataset_phase1(
|
|
279
|
+
agent=runtime or "",
|
|
280
|
+
dataset_name=dataset,
|
|
281
|
+
dataset_version=dataset_version,
|
|
282
|
+
endpoint=endpoint,
|
|
283
|
+
on_progress=lambda _p, m: log(m),
|
|
284
|
+
)
|
|
285
|
+
if not phase1.success:
|
|
286
|
+
raise phase1.error
|
|
287
|
+
ids = [*(ids or []), *phase1.value["sessionIds"]]
|
|
288
|
+
session_metadata = [*(session_metadata or []), *phase1.value["sessionMetadata"]]
|
|
289
|
+
start = engine.start(
|
|
290
|
+
"batch-evaluation",
|
|
291
|
+
{
|
|
292
|
+
"agent": runtime,
|
|
293
|
+
"evaluators": [*(evaluator or []), *(evaluator_arn or [])],
|
|
294
|
+
"name": name,
|
|
295
|
+
"region": region,
|
|
296
|
+
"endpoint": endpoint,
|
|
297
|
+
"sessionIds": ids,
|
|
298
|
+
"lookbackDays": days or None,
|
|
299
|
+
"sessionMetadata": session_metadata,
|
|
300
|
+
"source": "dataset" if dataset else "traces",
|
|
301
|
+
"dataset": dataset_info,
|
|
302
|
+
"kmsKeyArn": kms_key,
|
|
303
|
+
"onProgress": None if as_json else (lambda _s, m: typer.echo(m)),
|
|
304
|
+
},
|
|
305
|
+
)
|
|
306
|
+
if not start.success:
|
|
307
|
+
raise start.error
|
|
308
|
+
record = start.value
|
|
309
|
+
if wait:
|
|
310
|
+
final = wait_for_terminal(engine, "batch-evaluation", record["id"], on_tick=lambda s: log(f"Status: {s}"))
|
|
311
|
+
if final:
|
|
312
|
+
record = final
|
|
313
|
+
if as_json:
|
|
314
|
+
_job_json(record)
|
|
315
|
+
else:
|
|
316
|
+
typer.echo(f"\n✓ Batch evaluation started: {record['id']} ({record['status']})")
|
|
317
|
+
print_batch_eval_result(record)
|
|
318
|
+
if not wait:
|
|
319
|
+
typer.echo(f"\nNext: agentcore view batch-evaluation {record['id']}")
|
|
320
|
+
typer.echo("")
|
|
321
|
+
|
|
322
|
+
run_cli_command(as_json, run)
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
# ──────────────────────────────────────────────────────────────────────────────
|
|
326
|
+
# run insights
|
|
327
|
+
# ──────────────────────────────────────────────────────────────────────────────
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
def print_insights_result(record: dict[str, Any]) -> None:
|
|
331
|
+
categories = (record.get("failureAnalysisResult") or {}).get("failureCategories")
|
|
332
|
+
summaries = (record.get("evaluationResults") or {}).get("evaluatorSummaries")
|
|
333
|
+
if categories:
|
|
334
|
+
typer.echo("\nFailure Analysis:")
|
|
335
|
+
for cat in categories:
|
|
336
|
+
typer.echo(
|
|
337
|
+
f" {cat.get('failureCategoryName') or 'Unknown'}: {cat.get('failureCategoryDescription') or ''}"
|
|
338
|
+
)
|
|
339
|
+
for rc in cat.get("rootCauses") or []:
|
|
340
|
+
typer.echo(f" - {rc.get('rootCauseCategory') or ''}: {rc.get('rootCauseDescription') or ''}")
|
|
341
|
+
if rc.get("recommendation"):
|
|
342
|
+
typer.echo(f" Recommendation: {rc['recommendation']}")
|
|
343
|
+
elif summaries:
|
|
344
|
+
typer.echo("\nEvaluation Results:")
|
|
345
|
+
for s in summaries:
|
|
346
|
+
avg = (s.get("statistics") or {}).get("averageScore")
|
|
347
|
+
typer.echo(f" {s.get('evaluatorId')}: {to_fixed(avg, 2) if avg is not None else 'N/A'}")
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
@run_app.command(
|
|
351
|
+
"insights",
|
|
352
|
+
help="[preview] Run failure analysis across agent sessions",
|
|
353
|
+
cls=variadic("--insights", "-e", "--evaluator", "-s", "--session-ids"),
|
|
354
|
+
)
|
|
355
|
+
def run_insights(
|
|
356
|
+
runtime: str | None = typer.Option(None, "-r", "--runtime", help="Runtime name from project config"),
|
|
357
|
+
insights: list[str] | None = typer.Option(
|
|
358
|
+
None, "--insights", help="Insight type(s) (default: Builtin.Insight.FailureAnalysis)"
|
|
359
|
+
),
|
|
360
|
+
evaluator: list[str] | None = typer.Option(
|
|
361
|
+
None, "-e", "--evaluator", help="Evaluator(s) to include (needed for chaining into recommendations)"
|
|
362
|
+
),
|
|
363
|
+
online_eval_config_arn: str | None = typer.Option(
|
|
364
|
+
None, "--online-eval-config-arn", help="Use an existing OnlineEvaluationConfig as session source"
|
|
365
|
+
),
|
|
366
|
+
lookback_days: str | None = typer.Option(
|
|
367
|
+
None, "-d", "--lookback-days", help="Lookback window in days (default: 7)"
|
|
368
|
+
),
|
|
369
|
+
start_time: str | None = typer.Option(None, "--start-time", help="Session filter start time"),
|
|
370
|
+
end_time: str | None = typer.Option(None, "--end-time", help="Session filter end time"),
|
|
371
|
+
session_ids: list[str] | None = typer.Option(None, "-s", "--session-ids", help="Limit to specific session IDs"),
|
|
372
|
+
name: str | None = typer.Option(None, "-n", "--name", help="Job name (auto-generated if omitted)"),
|
|
373
|
+
kms_key: str | None = typer.Option(None, "--kms-key", help="KMS key ARN for encrypting insights job results"),
|
|
374
|
+
wait: bool = typer.Option(False, "--wait", help="Block until the job reaches a terminal state"),
|
|
375
|
+
region: str | None = typer.Option(None, "--region", help="AWS region (auto-detected if omitted)"),
|
|
376
|
+
endpoint: str | None = typer.Option(None, "--endpoint", help="Runtime endpoint name (e.g. PROMPT_V1)"),
|
|
377
|
+
as_json: bool = typer.Option(False, "--json", help="Output as JSON"),
|
|
378
|
+
) -> None:
|
|
379
|
+
require_project()
|
|
380
|
+
|
|
381
|
+
def log(message: str) -> None:
|
|
382
|
+
if not as_json:
|
|
383
|
+
typer.echo(message)
|
|
384
|
+
|
|
385
|
+
def run() -> None:
|
|
386
|
+
if name is not None and name.strip() == "":
|
|
387
|
+
raise ValidationError("--name must not be empty. Omit the flag to auto-generate a name.")
|
|
388
|
+
if kms_key and not is_valid_kms_key_arn(kms_key):
|
|
389
|
+
raise ValidationError(_KMS_HELP_ERROR)
|
|
390
|
+
engine = create_job_engine(ConfigIO())
|
|
391
|
+
days = parse_int(lookback_days) if lookback_days else None
|
|
392
|
+
if lookback_days and (days is None or days < 1 or days > 90):
|
|
393
|
+
raise ValidationError("--lookback-days must be a positive integer between 1 and 90.")
|
|
394
|
+
start = engine.start(
|
|
395
|
+
"insights",
|
|
396
|
+
{
|
|
397
|
+
"agent": runtime,
|
|
398
|
+
"insights": list(insights) if insights else ["Builtin.Insight.FailureAnalysis"],
|
|
399
|
+
"evaluators": list(evaluator) if evaluator else None,
|
|
400
|
+
"onlineEvalConfigArn": online_eval_config_arn,
|
|
401
|
+
"lookbackDays": days or None,
|
|
402
|
+
"startTime": start_time,
|
|
403
|
+
"endTime": end_time,
|
|
404
|
+
"sessionIds": list(session_ids) if session_ids else None,
|
|
405
|
+
"name": name,
|
|
406
|
+
"kmsKeyArn": kms_key,
|
|
407
|
+
"region": region,
|
|
408
|
+
"endpoint": endpoint,
|
|
409
|
+
"onProgress": None if as_json else (lambda _s, m: typer.echo(m)),
|
|
410
|
+
},
|
|
411
|
+
)
|
|
412
|
+
if not start.success:
|
|
413
|
+
raise start.error
|
|
414
|
+
record = start.value
|
|
415
|
+
if wait:
|
|
416
|
+
final = wait_for_terminal(engine, "insights", record["id"], on_tick=lambda s: log(f"Status: {s}"))
|
|
417
|
+
if final:
|
|
418
|
+
record = final
|
|
419
|
+
if as_json:
|
|
420
|
+
_job_json(record)
|
|
421
|
+
else:
|
|
422
|
+
typer.echo(f"\n✓ Insights job started: {record['id']} ({record['status']})")
|
|
423
|
+
print_insights_result(record)
|
|
424
|
+
if not wait:
|
|
425
|
+
typer.echo(f"\nNext: agentcore insights results --id {record['id']}")
|
|
426
|
+
typer.echo("")
|
|
427
|
+
|
|
428
|
+
run_cli_command(as_json, run)
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
# ──────────────────────────────────────────────────────────────────────────────
|
|
432
|
+
# run recommendation
|
|
433
|
+
# ──────────────────────────────────────────────────────────────────────────────
|
|
434
|
+
|
|
435
|
+
|
|
436
|
+
def print_recommendation_result(record: dict[str, Any]) -> None:
|
|
437
|
+
result = record.get("result") or {}
|
|
438
|
+
sys_result = result.get("systemPromptRecommendationResult") or {}
|
|
439
|
+
tool_result = result.get("toolDescriptionRecommendationResult") or {}
|
|
440
|
+
if sys_result.get("recommendedSystemPrompt"):
|
|
441
|
+
if sys_result.get("explanation"):
|
|
442
|
+
typer.echo("\n--- Explanation ---")
|
|
443
|
+
typer.echo(sys_result["explanation"])
|
|
444
|
+
typer.echo("\n+++ Recommended System Prompt +++")
|
|
445
|
+
typer.echo(sys_result["recommendedSystemPrompt"])
|
|
446
|
+
elif tool_result.get("tools"):
|
|
447
|
+
for t in tool_result["tools"]:
|
|
448
|
+
typer.echo(f"\nTool: {t.get('toolName')}")
|
|
449
|
+
if t.get("explanation"):
|
|
450
|
+
typer.echo(f"Explanation: {t['explanation']}")
|
|
451
|
+
typer.echo(f"Recommended: {t.get('recommendedToolDescription')}")
|
|
452
|
+
elif record.get("status") == "FAILED":
|
|
453
|
+
typer.echo(f"\nError: {failure_text(record)}")
|
|
454
|
+
if record.get("syncedVersionId"):
|
|
455
|
+
typer.echo(f"\nNew config bundle version {record['syncedVersionId']} applied to agentcore.json.")
|
|
456
|
+
|
|
457
|
+
|
|
458
|
+
@run_app.command(
|
|
459
|
+
"recommendation",
|
|
460
|
+
help="Optimize a system prompt or tool descriptions using agent traces as signal",
|
|
461
|
+
cls=variadic("--tool-desc-json-path", "--tools", "-s", "--session-id"),
|
|
462
|
+
)
|
|
463
|
+
def run_recommendation(
|
|
464
|
+
type_: str | None = typer.Option(
|
|
465
|
+
None, "-t", "--type", help="What to optimize: system-prompt or tool-description (default: system-prompt)"
|
|
466
|
+
),
|
|
467
|
+
runtime: str | None = typer.Option(None, "-r", "--runtime", help="Runtime name from project config"),
|
|
468
|
+
evaluator: str | None = typer.Option(
|
|
469
|
+
None,
|
|
470
|
+
"-e",
|
|
471
|
+
"--evaluator",
|
|
472
|
+
help="Evaluator name (exactly one). Required for system-prompt unless the trace source is a batch or online "
|
|
473
|
+
"evaluation, which inherits its evaluator",
|
|
474
|
+
),
|
|
475
|
+
prompt_file: str | None = typer.Option(None, "--prompt-file", help="Load the current system prompt from a file"),
|
|
476
|
+
inline: str | None = typer.Option(
|
|
477
|
+
None, "--inline", help="Provide the current system prompt or tool descriptions inline"
|
|
478
|
+
),
|
|
479
|
+
bundle_name: str | None = typer.Option(
|
|
480
|
+
None, "--bundle-name", help="Read current content from a deployed config bundle"
|
|
481
|
+
),
|
|
482
|
+
bundle_version: str | None = typer.Option(
|
|
483
|
+
None, "--bundle-version", help="Config bundle version (used with --bundle-name)"
|
|
484
|
+
),
|
|
485
|
+
system_prompt_json_path: str | None = typer.Option(
|
|
486
|
+
None,
|
|
487
|
+
"--system-prompt-json-path",
|
|
488
|
+
help='Field name under "configuration" in the bundle (e.g. "systemPrompt"). The CLI resolves it to the '
|
|
489
|
+
"full path automatically. Do not use bracket notation — use dot notation only.",
|
|
490
|
+
),
|
|
491
|
+
tool_desc_json_path: list[str] | None = typer.Option(
|
|
492
|
+
None,
|
|
493
|
+
"--tool-desc-json-path",
|
|
494
|
+
help="Tool name:field pairs for tool descriptions in a config bundle (e.g. --tool-desc-json-path "
|
|
495
|
+
'"search:searchDesc"). The CLI resolves each to the full path automatically.',
|
|
496
|
+
),
|
|
497
|
+
tools: list[str] | None = typer.Option(
|
|
498
|
+
None,
|
|
499
|
+
"--tools",
|
|
500
|
+
help='Tool name:description pairs (repeatable, e.g. --tools "search:Searches the web" --tools "calc:Does '
|
|
501
|
+
'math")',
|
|
502
|
+
),
|
|
503
|
+
spans_file: str | None = typer.Option(
|
|
504
|
+
None, "--spans-file", help="JSON file with OTEL session spans (use instead of CloudWatch traces)"
|
|
505
|
+
),
|
|
506
|
+
lookback: str = typer.Option(
|
|
507
|
+
"7",
|
|
508
|
+
"--lookback",
|
|
509
|
+
help="How far back to collect traces (days). Also bounds the online-evaluation reuse window: startTime = "
|
|
510
|
+
"now − lookback, endTime = now",
|
|
511
|
+
),
|
|
512
|
+
session_id: list[str] | None = typer.Option(
|
|
513
|
+
None, "-s", "--session-id", help="Limit trace collection to specific session IDs"
|
|
514
|
+
),
|
|
515
|
+
run_name: str | None = typer.Option(None, "-n", "--run", help="Run name prefix for the recommendation"),
|
|
516
|
+
region: str | None = typer.Option(None, "--region", help="AWS region"),
|
|
517
|
+
kms_key: str | None = typer.Option(None, "--kms-key", help="KMS key ARN for encrypting recommendation results"),
|
|
518
|
+
from_insights: str | None = typer.Option(
|
|
519
|
+
None, "--from-insights", help="Use a local insights run as trace source (resolves batch eval ARN)"
|
|
520
|
+
),
|
|
521
|
+
batch_evaluation_arn: str | None = typer.Option(
|
|
522
|
+
None, "--batch-evaluation-arn", help="Use a batch evaluation ARN directly as trace source"
|
|
523
|
+
),
|
|
524
|
+
online_evaluation_arn: str | None = typer.Option(
|
|
525
|
+
None, "--online-evaluation-arn", help="Use an online evaluation config ARN as trace source"
|
|
526
|
+
),
|
|
527
|
+
wait: bool = typer.Option(False, "--wait", help="Block until the recommendation reaches a terminal state"),
|
|
528
|
+
as_json: bool = typer.Option(False, "--json", help="Output as JSON"),
|
|
529
|
+
) -> None:
|
|
530
|
+
require_project()
|
|
531
|
+
source_flags = [
|
|
532
|
+
("--batch-evaluation-arn", bool(batch_evaluation_arn)),
|
|
533
|
+
("--from-insights", bool(from_insights)),
|
|
534
|
+
("--online-evaluation-arn", bool(online_evaluation_arn)),
|
|
535
|
+
("--spans-file", bool(spans_file)),
|
|
536
|
+
("--session-id", bool(session_id)),
|
|
537
|
+
]
|
|
538
|
+
has_source = any(is_set for _, is_set in source_flags)
|
|
539
|
+
if not runtime and not has_source and not as_json:
|
|
540
|
+
from agentcore.cli import interactive
|
|
541
|
+
from agentcore.cli.commands._run_wizards import run_recommendation_wizard
|
|
542
|
+
|
|
543
|
+
interactive.require_tty()
|
|
544
|
+
run_recommendation_wizard()
|
|
545
|
+
raise typer.Exit(0)
|
|
546
|
+
|
|
547
|
+
set_flags = [n for n, is_set in source_flags if is_set]
|
|
548
|
+
if len(set_flags) > 1:
|
|
549
|
+
fail_early(
|
|
550
|
+
as_json,
|
|
551
|
+
f"Only one trace source may be specified. Got: {', '.join(set_flags)}. Use exactly one of "
|
|
552
|
+
"--batch-evaluation-arn, --from-insights, --online-evaluation-arn, --spans-file, or --session-id.",
|
|
553
|
+
)
|
|
554
|
+
type_key = type_ if type_ is not None else "system-prompt"
|
|
555
|
+
rec_type = RECOMMENDATION_TYPE_MAP.get(type_key)
|
|
556
|
+
if not rec_type:
|
|
557
|
+
fail_early(as_json, f'Invalid --type "{type_key}". Must be one of: {", ".join(RECOMMENDATION_TYPE_MAP)}')
|
|
558
|
+
is_batch = bool(from_insights or batch_evaluation_arn)
|
|
559
|
+
is_online = bool(online_evaluation_arn)
|
|
560
|
+
no_agent = is_batch or is_online
|
|
561
|
+
if not runtime and not no_agent:
|
|
562
|
+
fail_early(
|
|
563
|
+
as_json,
|
|
564
|
+
"--runtime is required (unless --from-insights, --batch-evaluation-arn, or --online-evaluation-arn is "
|
|
565
|
+
"provided)",
|
|
566
|
+
)
|
|
567
|
+
if rec_type == "SYSTEM_PROMPT_RECOMMENDATION" and not evaluator and not no_agent:
|
|
568
|
+
fail_early(
|
|
569
|
+
as_json,
|
|
570
|
+
"--evaluator is required for system-prompt recommendations (unless using --from-insights, "
|
|
571
|
+
"--batch-evaluation-arn, or --online-evaluation-arn)",
|
|
572
|
+
)
|
|
573
|
+
if prompt_file:
|
|
574
|
+
input_source = "file"
|
|
575
|
+
elif inline:
|
|
576
|
+
input_source = "inline"
|
|
577
|
+
elif bundle_name:
|
|
578
|
+
input_source = "config-bundle"
|
|
579
|
+
else:
|
|
580
|
+
input_source = "inline"
|
|
581
|
+
if is_batch:
|
|
582
|
+
trace_source = "batch-evaluation"
|
|
583
|
+
elif is_online:
|
|
584
|
+
trace_source = "online-evaluation"
|
|
585
|
+
elif spans_file:
|
|
586
|
+
trace_source = "spans-file"
|
|
587
|
+
elif session_id:
|
|
588
|
+
trace_source = "sessions"
|
|
589
|
+
else:
|
|
590
|
+
trace_source = "cloudwatch"
|
|
591
|
+
pairs = []
|
|
592
|
+
for pair in tool_desc_json_path or []:
|
|
593
|
+
idx = pair.find(":")
|
|
594
|
+
if idx > 0:
|
|
595
|
+
pairs.append({"toolName": pair[:idx], "toolDescriptionJsonPath": pair[idx + 1 :]})
|
|
596
|
+
|
|
597
|
+
def run() -> None:
|
|
598
|
+
engine = create_job_engine(ConfigIO())
|
|
599
|
+
start = engine.start(
|
|
600
|
+
"recommendation",
|
|
601
|
+
{
|
|
602
|
+
"type": rec_type,
|
|
603
|
+
"agent": runtime or "",
|
|
604
|
+
"evaluators": [evaluator] if evaluator else [],
|
|
605
|
+
"promptFile": prompt_file,
|
|
606
|
+
"inlineContent": inline,
|
|
607
|
+
"bundleName": bundle_name,
|
|
608
|
+
"bundleVersion": bundle_version,
|
|
609
|
+
"systemPromptJsonPath": system_prompt_json_path,
|
|
610
|
+
"toolDescJsonPaths": pairs or None,
|
|
611
|
+
"tools": list(tools) if tools else None,
|
|
612
|
+
"lookbackDays": parse_int(lookback),
|
|
613
|
+
"sessionIds": list(session_id) if session_id else None,
|
|
614
|
+
"spansFile": spans_file,
|
|
615
|
+
"fromInsights": from_insights,
|
|
616
|
+
"batchEvaluationArn": batch_evaluation_arn,
|
|
617
|
+
"onlineEvaluationArn": online_evaluation_arn,
|
|
618
|
+
"recommendationName": run_name,
|
|
619
|
+
"region": region,
|
|
620
|
+
"kmsKeyArn": kms_key,
|
|
621
|
+
"inputSource": input_source,
|
|
622
|
+
"traceSource": trace_source,
|
|
623
|
+
"onProgress": None if as_json else (lambda _s, m: typer.echo(m)),
|
|
624
|
+
},
|
|
625
|
+
)
|
|
626
|
+
if not start.success:
|
|
627
|
+
raise start.error
|
|
628
|
+
record = start.value
|
|
629
|
+
if wait:
|
|
630
|
+
|
|
631
|
+
def tick(status: str) -> None:
|
|
632
|
+
if not as_json:
|
|
633
|
+
typer.echo(f"Status: {status}")
|
|
634
|
+
|
|
635
|
+
final = wait_for_terminal(engine, "recommendation", record["id"], on_tick=tick)
|
|
636
|
+
if final:
|
|
637
|
+
record = final
|
|
638
|
+
if as_json:
|
|
639
|
+
_job_json(record)
|
|
640
|
+
else:
|
|
641
|
+
typer.echo(f"\n✓ Recommendation started: {record['id']} ({record['status']})")
|
|
642
|
+
print_recommendation_result(record)
|
|
643
|
+
if not wait:
|
|
644
|
+
suffix = (
|
|
645
|
+
" — the new config bundle will be applied to agentcore.json automatically."
|
|
646
|
+
if input_source == "config-bundle"
|
|
647
|
+
else ""
|
|
648
|
+
)
|
|
649
|
+
typer.echo(f"\nNext: agentcore view recommendation {record['id']}{suffix}")
|
|
650
|
+
typer.echo("")
|
|
651
|
+
|
|
652
|
+
run_cli_command(as_json, run)
|
|
653
|
+
|
|
654
|
+
|
|
655
|
+
# ──────────────────────────────────────────────────────────────────────────────
|
|
656
|
+
# run ab-test
|
|
657
|
+
# ──────────────────────────────────────────────────────────────────────────────
|
|
658
|
+
|
|
659
|
+
_AB_TEST_EPILOG = """\b
|
|
660
|
+
Config-bundle mode example:
|
|
661
|
+
agentcore run ab-test -n MyTest -g MyGateway \\
|
|
662
|
+
--control-bundle PromptV1 --control-version LATEST \\
|
|
663
|
+
--treatment-bundle PromptV2 --treatment-version LATEST \\
|
|
664
|
+
--online-eval QualityEval
|
|
665
|
+
|
|
666
|
+
\b
|
|
667
|
+
Target-based mode example:
|
|
668
|
+
agentcore run ab-test -n MyTest -g MyGateway --mode target-based \\
|
|
669
|
+
--control-target prod-target --treatment-target staging-target \\
|
|
670
|
+
--control-online-eval ProdEval --treatment-online-eval StagingEval
|
|
671
|
+
"""
|
|
672
|
+
|
|
673
|
+
|
|
674
|
+
def weight_error(control_raw: str, treatment_raw: str) -> tuple[int | None, int | None, str | None]:
|
|
675
|
+
cw, tw = parse_int(control_raw), parse_int(treatment_raw)
|
|
676
|
+
if cw is None or cw < 0 or cw > 100:
|
|
677
|
+
return cw, tw, f'Invalid --control-weight "{control_raw}". Must be an integer between 0 and 100.'
|
|
678
|
+
if tw is None or tw < 0 or tw > 100:
|
|
679
|
+
return cw, tw, f'Invalid --treatment-weight "{treatment_raw}". Must be an integer between 0 and 100.'
|
|
680
|
+
if cw + tw != 100:
|
|
681
|
+
return cw, tw, f"Variant weights must sum to 100 (got {cw} + {tw} = {cw + tw})."
|
|
682
|
+
return cw, tw, None
|
|
683
|
+
|
|
684
|
+
|
|
685
|
+
def start_ab_test(opts: dict[str, Any], *, wait: bool, as_json: bool) -> None:
|
|
686
|
+
engine = create_job_engine(ConfigIO())
|
|
687
|
+
start = engine.start("ab-test", opts)
|
|
688
|
+
if not start.success:
|
|
689
|
+
raise start.error
|
|
690
|
+
record = start.value
|
|
691
|
+
if wait:
|
|
692
|
+
|
|
693
|
+
def tick(status: str) -> None:
|
|
694
|
+
if not as_json:
|
|
695
|
+
typer.echo(f"Status: {status}")
|
|
696
|
+
|
|
697
|
+
final = wait_for_terminal(engine, "ab-test", record["id"], on_tick=tick)
|
|
698
|
+
if final:
|
|
699
|
+
record = final
|
|
700
|
+
if as_json:
|
|
701
|
+
_job_json(record)
|
|
702
|
+
else:
|
|
703
|
+
typer.echo(f"\n✓ A/B test started: {record['id']} ({record['status']})")
|
|
704
|
+
print_ab_test_detail(record)
|
|
705
|
+
if not wait:
|
|
706
|
+
typer.echo(f"\nNext: agentcore view ab-test {record['id']}")
|
|
707
|
+
typer.echo("")
|
|
708
|
+
|
|
709
|
+
|
|
710
|
+
@run_app.command(
|
|
711
|
+
"ab-test", help="Start an A/B test comparing two config-bundle or gateway-target variants", epilog=_AB_TEST_EPILOG
|
|
712
|
+
)
|
|
713
|
+
def run_ab_test(
|
|
714
|
+
name: str | None = typer.Option(None, "-n", "--name", help="Name for the A/B test [non-interactive]"),
|
|
715
|
+
gateway: str | None = typer.Option(
|
|
716
|
+
None, "-g", "--gateway", help="Gateway name (must be deployed) [non-interactive]"
|
|
717
|
+
),
|
|
718
|
+
mode: str = typer.Option(
|
|
719
|
+
"config-bundle", "-m", "--mode", help="config-bundle | target-based (default: config-bundle)"
|
|
720
|
+
),
|
|
721
|
+
description: str | None = typer.Option(None, "--description", help="Description"),
|
|
722
|
+
runtime: str | None = typer.Option(None, "-r", "--runtime", help="Runtime name (recorded as the agent)"),
|
|
723
|
+
control_weight: str = typer.Option("50", "--control-weight", help="Control traffic weight 0-100 (default: 50)"),
|
|
724
|
+
treatment_weight: str = typer.Option(
|
|
725
|
+
"50", "--treatment-weight", help="Treatment traffic weight 0-100 (default: 50)"
|
|
726
|
+
),
|
|
727
|
+
role_arn: str | None = typer.Option(None, "--role-arn", help="Execution role ARN (auto-created if omitted)"),
|
|
728
|
+
disable_on_create: bool = typer.Option(
|
|
729
|
+
False, "--disable-on-create", help="Create without starting (default: enabled)"
|
|
730
|
+
),
|
|
731
|
+
region: str | None = typer.Option(None, "--region", help="AWS region (auto-detected if omitted)"),
|
|
732
|
+
wait: bool = typer.Option(False, "--wait", help="Block until terminal state"),
|
|
733
|
+
as_json: bool = typer.Option(False, "--json", help="Output as JSON"),
|
|
734
|
+
control_bundle: str | None = typer.Option(
|
|
735
|
+
None, "--control-bundle", help="[config-bundle] Control bundle name or ARN"
|
|
736
|
+
),
|
|
737
|
+
control_version: str | None = typer.Option(
|
|
738
|
+
None, "--control-version", help="[config-bundle] Control bundle version (or LATEST)"
|
|
739
|
+
),
|
|
740
|
+
treatment_bundle: str | None = typer.Option(
|
|
741
|
+
None, "--treatment-bundle", help="[config-bundle] Treatment bundle name or ARN"
|
|
742
|
+
),
|
|
743
|
+
treatment_version: str | None = typer.Option(
|
|
744
|
+
None, "--treatment-version", help="[config-bundle] Treatment bundle version (or LATEST)"
|
|
745
|
+
),
|
|
746
|
+
online_eval: str | None = typer.Option(
|
|
747
|
+
None, "--online-eval", help="[config-bundle] Shared online eval config name or ARN"
|
|
748
|
+
),
|
|
749
|
+
control_target: str | None = typer.Option(
|
|
750
|
+
None, "--control-target", help="[target-based] Control gateway-target name"
|
|
751
|
+
),
|
|
752
|
+
treatment_target: str | None = typer.Option(
|
|
753
|
+
None, "--treatment-target", help="[target-based] Treatment gateway-target name"
|
|
754
|
+
),
|
|
755
|
+
control_online_eval: str | None = typer.Option(
|
|
756
|
+
None, "--control-online-eval", help="[target-based] Online eval for control endpoint (required)"
|
|
757
|
+
),
|
|
758
|
+
treatment_online_eval: str | None = typer.Option(
|
|
759
|
+
None, "--treatment-online-eval", help="[target-based] Online eval for treatment endpoint (required)"
|
|
760
|
+
),
|
|
761
|
+
gateway_filter: str | None = typer.Option(
|
|
762
|
+
None,
|
|
763
|
+
"--gateway-filter",
|
|
764
|
+
help='Single gateway target path pattern to scope the test (e.g. "/orders/*"). Applies to both modes. '
|
|
765
|
+
"Optional; omit for no gateway filter.",
|
|
766
|
+
),
|
|
767
|
+
) -> None:
|
|
768
|
+
require_project()
|
|
769
|
+
if not name and not as_json:
|
|
770
|
+
from agentcore.cli import interactive
|
|
771
|
+
from agentcore.cli.commands._run_wizards import run_ab_test_wizard
|
|
772
|
+
|
|
773
|
+
interactive.require_tty()
|
|
774
|
+
run_ab_test_wizard()
|
|
775
|
+
raise typer.Exit(0)
|
|
776
|
+
if not name or not gateway:
|
|
777
|
+
fail_early(as_json, "--name and --gateway are required in non-interactive mode")
|
|
778
|
+
if mode not in ("config-bundle", "target-based"):
|
|
779
|
+
fail_early(as_json, f'Invalid --mode "{mode}". Must be one of: config-bundle, target-based')
|
|
780
|
+
cw, tw, error = weight_error(control_weight, treatment_weight)
|
|
781
|
+
if error:
|
|
782
|
+
fail_early(as_json, error)
|
|
783
|
+
|
|
784
|
+
opts = {
|
|
785
|
+
"name": name,
|
|
786
|
+
"mode": mode,
|
|
787
|
+
"description": description,
|
|
788
|
+
"gateway": gateway,
|
|
789
|
+
"agent": runtime,
|
|
790
|
+
"controlBundle": control_bundle,
|
|
791
|
+
"controlVersion": control_version,
|
|
792
|
+
"treatmentBundle": treatment_bundle,
|
|
793
|
+
"treatmentVersion": treatment_version,
|
|
794
|
+
"onlineEval": online_eval,
|
|
795
|
+
"runtime": runtime,
|
|
796
|
+
"controlTarget": control_target,
|
|
797
|
+
"treatmentTarget": treatment_target,
|
|
798
|
+
"controlOnlineEval": control_online_eval,
|
|
799
|
+
"treatmentOnlineEval": treatment_online_eval,
|
|
800
|
+
"gatewayFilter": gateway_filter,
|
|
801
|
+
"controlWeight": cw,
|
|
802
|
+
"treatmentWeight": tw,
|
|
803
|
+
"enableOnCreate": not disable_on_create,
|
|
804
|
+
"region": region,
|
|
805
|
+
"roleArn": role_arn,
|
|
806
|
+
"onProgress": None if as_json else (lambda _s, m: typer.echo(m)),
|
|
807
|
+
}
|
|
808
|
+
run_cli_command(as_json, lambda: start_ab_test(opts, wait=wait, as_json=as_json))
|