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
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""Helpers shared by the eval/jobs command modules (run, view, history, pause/resume, ...)."""
|
|
2
|
+
|
|
3
|
+
from collections.abc import Callable
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
import typer
|
|
7
|
+
|
|
8
|
+
from agentcore.cli.commands.logs.guards import require_project
|
|
9
|
+
from agentcore.lib.result import Err, Ok
|
|
10
|
+
from agentcore.lib.utils.json_format import to_json_string
|
|
11
|
+
|
|
12
|
+
__all__ = ["fail_early", "print_json", "red", "require_project", "result_json"]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def print_json(payload: dict[str, Any]) -> None:
|
|
16
|
+
"""``console.log(JSON.stringify(payload))`` with undefined (None) top-level keys dropped."""
|
|
17
|
+
typer.echo(to_json_string({k: v for k, v in payload.items() if v is not None}, None))
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def red(message: str) -> None:
|
|
21
|
+
"""Ink ``<Text color="red">`` (stdout)."""
|
|
22
|
+
typer.secho(message, fg=typer.colors.RED)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def fail_early(as_json: bool, error: str) -> None:
|
|
26
|
+
"""Upstream's pre-validation pattern: JSON error line or red text, then exit 1."""
|
|
27
|
+
if as_json:
|
|
28
|
+
print_json({"success": False, "error": error})
|
|
29
|
+
else:
|
|
30
|
+
red(error)
|
|
31
|
+
raise typer.Exit(1)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def result_json(result: Ok | Err, value_key: Callable[[Any], dict] | None = None) -> dict[str, Any]:
|
|
35
|
+
from agentcore.lib import serialize_result
|
|
36
|
+
|
|
37
|
+
if result.success and value_key is not None:
|
|
38
|
+
return {"success": True, **value_key(result.value)}
|
|
39
|
+
return serialize_result(result)
|
|
@@ -0,0 +1,639 @@
|
|
|
1
|
+
"""Prompt-based replacements for the `run` TUI flows.
|
|
2
|
+
|
|
3
|
+
Question order follows tui/screens/run-eval/RunBatchEvalFlow.tsx, tui/screens/recommendation/*
|
|
4
|
+
and tui/screens/run-ab-test/RunABTestFlow.tsx.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import json
|
|
8
|
+
import os
|
|
9
|
+
import re
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
import typer
|
|
13
|
+
|
|
14
|
+
from agentcore.aws import agentcore_control as control
|
|
15
|
+
from agentcore.aws import agentcore_datasets as datasets_api
|
|
16
|
+
from agentcore.aws import region as _region
|
|
17
|
+
from agentcore.aws.account import validate_aws_credentials
|
|
18
|
+
from agentcore.cli import interactive
|
|
19
|
+
from agentcore.cli.errors import get_error_message
|
|
20
|
+
from agentcore.lib import ConfigIO
|
|
21
|
+
from agentcore.lib.schemas.io.config_io import to_jsonable
|
|
22
|
+
from agentcore.operations import resolve_agent as _resolve_agent
|
|
23
|
+
from agentcore.operations.dataset.resolve_dataset import resolve_dataset
|
|
24
|
+
from agentcore.operations.eval.run_eval import discover_sessions
|
|
25
|
+
from agentcore.operations.jobs import create_job_engine, run_dataset_phase1
|
|
26
|
+
from agentcore.operations.jobs.shared.format import parse_int, parse_js_date
|
|
27
|
+
from agentcore.schema import is_valid_kms_key_arn
|
|
28
|
+
|
|
29
|
+
Choice = interactive.Choice
|
|
30
|
+
DEFAULT_LOOKBACK_DAYS = 7
|
|
31
|
+
_KMS_INVALID = "Invalid KMS key ARN (e.g. arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012)"
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _require_creds() -> None:
|
|
35
|
+
try:
|
|
36
|
+
validate_aws_credentials()
|
|
37
|
+
except Exception as exc: # noqa: BLE001
|
|
38
|
+
typer.secho("AWS credentials required", fg=typer.colors.RED, err=True)
|
|
39
|
+
typer.echo(get_error_message(exc), err=True)
|
|
40
|
+
raise typer.Exit(1) from None
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _error(message: str, detail: str | None = None) -> None:
|
|
44
|
+
typer.secho(message, fg=typer.colors.RED, err=True)
|
|
45
|
+
if detail:
|
|
46
|
+
typer.echo(detail, err=True)
|
|
47
|
+
raise typer.Exit(1)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _evaluator_choices(evaluators: list[dict[str, Any]]) -> list[Choice]:
|
|
51
|
+
return [
|
|
52
|
+
Choice(
|
|
53
|
+
e["evaluatorName"],
|
|
54
|
+
e["evaluatorArn"],
|
|
55
|
+
"Built-in evaluator"
|
|
56
|
+
if e.get("evaluatorType") == "Builtin"
|
|
57
|
+
else (e.get("description") or "Custom evaluator"),
|
|
58
|
+
)
|
|
59
|
+
for e in evaluators
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _validate_days(value: str) -> str | None:
|
|
64
|
+
days = parse_int(value)
|
|
65
|
+
if days is None:
|
|
66
|
+
return "Must be a number"
|
|
67
|
+
return None if 1 <= days <= 90 else "Must be between 1 and 90"
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def _validate_kms(value: str) -> str | None:
|
|
71
|
+
return None if not value or is_valid_kms_key_arn(value) else _KMS_INVALID
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def _session_label(session: dict[str, Any]) -> tuple[str, str]:
|
|
75
|
+
parsed = parse_js_date(session.get("firstSeen")) if session.get("firstSeen") else None
|
|
76
|
+
date = ""
|
|
77
|
+
if parsed is not None:
|
|
78
|
+
local = parsed.astimezone()
|
|
79
|
+
hour12 = local.hour % 12 or 12
|
|
80
|
+
months = ("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec")
|
|
81
|
+
date = f"{months[local.month - 1]} {local.day}, {hour12:02d}:{local.minute:02d} {'AM' if local.hour < 12 else 'PM'}"
|
|
82
|
+
return session["sessionId"], f"{session.get('spanCount', 0)} spans · {date}"
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def _pick_sessions(runtime_id: str, region: str, days: int, title: str) -> list[str]:
|
|
86
|
+
typer.echo("Discovering sessions...")
|
|
87
|
+
sessions = discover_sessions(runtime_id=runtime_id, region=region, lookback_days=days)
|
|
88
|
+
if not sessions:
|
|
89
|
+
_error(f"No sessions found in the last {days} day(s). Invoke the agent first and wait for traces to propagate.")
|
|
90
|
+
count = len(sessions)
|
|
91
|
+
typer.echo(f"Found {count} session{'' if count == 1 else 's'} — select one or more")
|
|
92
|
+
while True:
|
|
93
|
+
picked = interactive.checkbox(
|
|
94
|
+
title, [Choice(_session_label(s)[0], s["sessionId"], _session_label(s)[1]) for s in sessions]
|
|
95
|
+
)
|
|
96
|
+
if picked:
|
|
97
|
+
return picked
|
|
98
|
+
typer.echo("Select at least one session.", err=True)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def _ground_truth(session_ids: list[str]) -> list[dict[str, Any]] | None:
|
|
102
|
+
mode = interactive.select(
|
|
103
|
+
"Ground truth (optional)",
|
|
104
|
+
[
|
|
105
|
+
Choice("Skip", "skip", "No ground truth"),
|
|
106
|
+
Choice("Load from file", "file", "JSON file with session metadata and ground truth"),
|
|
107
|
+
Choice("Enter manually", "inline", "Type assertions, trajectory, and expected response"),
|
|
108
|
+
],
|
|
109
|
+
)
|
|
110
|
+
if mode == "skip":
|
|
111
|
+
return None
|
|
112
|
+
if mode == "file":
|
|
113
|
+
typer.echo("Select a JSON file with session ground truth (assertions, expected trajectory, turns).")
|
|
114
|
+
while True:
|
|
115
|
+
path = interactive.text("path/to/ground-truth.json")
|
|
116
|
+
try:
|
|
117
|
+
with open(os.path.abspath(os.path.expanduser(path.strip())), encoding="utf-8") as fh:
|
|
118
|
+
parsed = json.load(fh)
|
|
119
|
+
metadata = parsed if isinstance(parsed, list) else (parsed or {}).get("sessionMetadata")
|
|
120
|
+
if not isinstance(metadata, list):
|
|
121
|
+
typer.secho('File must be a JSON array or contain a "sessionMetadata" array', fg="red")
|
|
122
|
+
continue
|
|
123
|
+
return metadata
|
|
124
|
+
except Exception as exc: # noqa: BLE001
|
|
125
|
+
typer.secho(f"Failed to load file: {exc}", fg="red")
|
|
126
|
+
label = session_ids[0] if len(session_ids) == 1 else f"{len(session_ids)} sessions"
|
|
127
|
+
typer.echo(f"Session: {label}")
|
|
128
|
+
typer.echo("All fields are optional. Press Enter on empty to skip to next section.")
|
|
129
|
+
assertions = _collect_lines("Assertions:")
|
|
130
|
+
trajectory = _collect_lines("Expected trajectory:")
|
|
131
|
+
response = interactive.text("Expected response (targets last trace):")
|
|
132
|
+
inline: dict[str, Any] = {}
|
|
133
|
+
if assertions:
|
|
134
|
+
inline["assertions"] = [{"text": a} for a in assertions]
|
|
135
|
+
if trajectory:
|
|
136
|
+
inline["expectedTrajectory"] = {"toolNames": trajectory}
|
|
137
|
+
if response:
|
|
138
|
+
inline["turns"] = [{"input": {"prompt": ""}, "expectedResponse": {"text": response}}]
|
|
139
|
+
return [{"sessionId": sid, "groundTruth": {"inline": inline}} for sid in session_ids]
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def _collect_lines(label: str) -> list[str]:
|
|
143
|
+
values: list[str] = []
|
|
144
|
+
while True:
|
|
145
|
+
value = interactive.text(f"{label} ({len(values) + 1})")
|
|
146
|
+
if not value:
|
|
147
|
+
return values
|
|
148
|
+
values.append(value)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
# ──────────────────────────────────────────────────────────────────────────────
|
|
152
|
+
# Batch evaluation
|
|
153
|
+
# ──────────────────────────────────────────────────────────────────────────────
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def run_batch_eval_wizard() -> None:
|
|
157
|
+
_require_creds()
|
|
158
|
+
context = _resolve_agent.load_deployed_project_config()
|
|
159
|
+
targets = context.aws_targets or []
|
|
160
|
+
region = (targets[0].region if targets else None) or _region.detect_region().region
|
|
161
|
+
evaluators = control.list_evaluators(region=region)["evaluators"]
|
|
162
|
+
deployed = to_jsonable(context.deployed_state)
|
|
163
|
+
deployed_names: set[str] = set()
|
|
164
|
+
runtime_ids: dict[str, str] = {}
|
|
165
|
+
for target in (deployed.get("targets") or {}).values():
|
|
166
|
+
for name, state in (((target or {}).get("resources") or {}).get("runtimes") or {}).items():
|
|
167
|
+
deployed_names.add(name)
|
|
168
|
+
runtime_ids[name] = state["runtimeId"]
|
|
169
|
+
project = to_jsonable(context.project)
|
|
170
|
+
agents = [r for r in project.get("runtimes") or [] if r["name"] in deployed_names]
|
|
171
|
+
if not agents:
|
|
172
|
+
_error(
|
|
173
|
+
"No agents found in project. Run `agentcore add agent` first."
|
|
174
|
+
if not project.get("runtimes")
|
|
175
|
+
else "No deployed agents found. Run `agentcore deploy` first."
|
|
176
|
+
)
|
|
177
|
+
if not evaluators:
|
|
178
|
+
_error("No evaluators found in your account. Create an evaluator first.")
|
|
179
|
+
|
|
180
|
+
source = interactive.select(
|
|
181
|
+
"Evaluation source:",
|
|
182
|
+
[
|
|
183
|
+
Choice("Dataset", "dataset", "Invoke agent with dataset scenarios"),
|
|
184
|
+
Choice("Historical traces", "traces", "Evaluate existing sessions"),
|
|
185
|
+
],
|
|
186
|
+
)
|
|
187
|
+
dataset = dataset_version = None
|
|
188
|
+
if source == "dataset":
|
|
189
|
+
datasets = project.get("datasets") or []
|
|
190
|
+
labels = {
|
|
191
|
+
"AGENTCORE_EVALUATION_PREDEFINED_V1": "Predefined Turns",
|
|
192
|
+
"AGENTCORE_EVALUATION_SIMULATED_V1": "Actor Simulator",
|
|
193
|
+
}
|
|
194
|
+
if len(datasets) == 1:
|
|
195
|
+
dataset = datasets[0]["name"]
|
|
196
|
+
elif datasets:
|
|
197
|
+
dataset = interactive.select(
|
|
198
|
+
"Select dataset:",
|
|
199
|
+
[Choice(d["name"], d["name"], labels.get(d["schemaType"], d["schemaType"])) for d in datasets],
|
|
200
|
+
)
|
|
201
|
+
if dataset:
|
|
202
|
+
versions = [Choice("Local file", "local", "fastest iteration, no push required")]
|
|
203
|
+
try:
|
|
204
|
+
resolved = resolve_dataset(dataset)
|
|
205
|
+
listed = datasets_api.list_dataset_versions(region=resolved.region, dataset_id=resolved.dataset_id)
|
|
206
|
+
versions.append(Choice("DRAFT", "DRAFT", "latest pushed content"))
|
|
207
|
+
for v in sorted(listed.get("versions") or [], key=lambda v: v.get("createdAt") or 0, reverse=True):
|
|
208
|
+
versions.append(
|
|
209
|
+
Choice(
|
|
210
|
+
f"Version {v['datasetVersion']}", v["datasetVersion"], f"{v.get('exampleCount')} examples"
|
|
211
|
+
)
|
|
212
|
+
)
|
|
213
|
+
except Exception: # noqa: BLE001, S110 - not deployed yet: local only
|
|
214
|
+
pass
|
|
215
|
+
picked = interactive.select(f"Select version for {dataset}:", versions)
|
|
216
|
+
dataset_version = None if picked == "local" else picked
|
|
217
|
+
|
|
218
|
+
agent = agents[0]["name"]
|
|
219
|
+
if len(agents) > 1:
|
|
220
|
+
agent = interactive.select(
|
|
221
|
+
"Select agent to evaluate", [Choice(a["name"], a["name"], a.get("build")) for a in agents]
|
|
222
|
+
)
|
|
223
|
+
while True:
|
|
224
|
+
chosen = interactive.checkbox("Select evaluators", _evaluator_choices(evaluators))
|
|
225
|
+
if chosen:
|
|
226
|
+
break
|
|
227
|
+
typer.echo("Select at least one evaluator.", err=True)
|
|
228
|
+
names = [e["evaluatorName"] for e in evaluators if e["evaluatorArn"] in chosen]
|
|
229
|
+
|
|
230
|
+
days = DEFAULT_LOOKBACK_DAYS
|
|
231
|
+
session_ids: list[str] = []
|
|
232
|
+
session_metadata = None
|
|
233
|
+
if source == "traces":
|
|
234
|
+
typer.echo("Note: Traces may take 5–10 min to appear after agent invocations.")
|
|
235
|
+
days = (
|
|
236
|
+
parse_int(
|
|
237
|
+
interactive.text("Lookback window (days)", default=str(DEFAULT_LOOKBACK_DAYS), validate=_validate_days)
|
|
238
|
+
)
|
|
239
|
+
or DEFAULT_LOOKBACK_DAYS
|
|
240
|
+
)
|
|
241
|
+
session_ids = _pick_sessions(runtime_ids[agent], region, days, "Select sessions to evaluate")
|
|
242
|
+
session_metadata = _ground_truth(session_ids)
|
|
243
|
+
kms = interactive.text("KMS key ARN for encryption (optional, press Enter to skip)", validate=_validate_kms)
|
|
244
|
+
typer.echo("Optional — leave blank for auto-generated name.")
|
|
245
|
+
name = interactive.text("Batch evaluation name")
|
|
246
|
+
|
|
247
|
+
rows = [("Agent", agent), ("Evaluators", ", ".join(names))]
|
|
248
|
+
if source == "dataset":
|
|
249
|
+
rows.append(("Dataset", f"{dataset}@{dataset_version or 'LOCAL'}"))
|
|
250
|
+
else:
|
|
251
|
+
rows += [("Lookback", f"{days} days"), ("Sessions", str(len(session_ids)))]
|
|
252
|
+
if kms:
|
|
253
|
+
rows.append(("KMS Key", kms))
|
|
254
|
+
rows.append(("Name", name or "(auto-generated)"))
|
|
255
|
+
for label, value in rows:
|
|
256
|
+
typer.echo(f" {label}: {value}")
|
|
257
|
+
if not interactive.confirm("Start batch evaluation?", default=True):
|
|
258
|
+
typer.echo("Cancelled.")
|
|
259
|
+
return
|
|
260
|
+
|
|
261
|
+
if source == "dataset":
|
|
262
|
+
phase1 = run_dataset_phase1(
|
|
263
|
+
agent=agent,
|
|
264
|
+
dataset_name=dataset or "",
|
|
265
|
+
dataset_version=dataset_version,
|
|
266
|
+
on_progress=lambda _p, m: typer.echo(m),
|
|
267
|
+
)
|
|
268
|
+
if not phase1.success:
|
|
269
|
+
_error("Batch evaluation failed", str(phase1.error))
|
|
270
|
+
session_ids = phase1.value["sessionIds"]
|
|
271
|
+
session_metadata = phase1.value["sessionMetadata"]
|
|
272
|
+
|
|
273
|
+
engine = create_job_engine(ConfigIO())
|
|
274
|
+
result = engine.start(
|
|
275
|
+
"batch-evaluation",
|
|
276
|
+
{
|
|
277
|
+
"agent": agent,
|
|
278
|
+
"evaluators": chosen,
|
|
279
|
+
"name": name or None,
|
|
280
|
+
"sessionIds": session_ids or None,
|
|
281
|
+
"lookbackDays": days,
|
|
282
|
+
"sessionMetadata": session_metadata,
|
|
283
|
+
"source": "dataset" if dataset else "traces",
|
|
284
|
+
"dataset": {"id": dataset, "version": dataset_version or "LOCAL"} if dataset else None,
|
|
285
|
+
"kmsKeyArn": kms or None,
|
|
286
|
+
},
|
|
287
|
+
)
|
|
288
|
+
if not result.success:
|
|
289
|
+
_error("Batch evaluation failed", str(result.error))
|
|
290
|
+
record = result.value
|
|
291
|
+
typer.secho(f"✓ {record['id']} ({record['status']})", fg=typer.colors.GREEN)
|
|
292
|
+
typer.echo(f"Agent: {agent} Evaluators: {', '.join(names)}")
|
|
293
|
+
typer.echo("\nWhen it completes, view it in Batch Eval Jobs.")
|
|
294
|
+
typer.echo(f"Next: agentcore view batch-evaluation {record['id']}")
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
# ──────────────────────────────────────────────────────────────────────────────
|
|
298
|
+
# Recommendation
|
|
299
|
+
# ──────────────────────────────────────────────────────────────────────────────
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
def collect_string_fields(obj: Any, prefix: str, json_path_prefix: str) -> list[dict[str, str]]:
|
|
303
|
+
"""All non-empty string leaves with dot paths and JSONPath equivalents (RecommendationFlow)."""
|
|
304
|
+
fields: list[dict[str, str]] = []
|
|
305
|
+
if not isinstance(obj, dict):
|
|
306
|
+
return fields
|
|
307
|
+
for key, value in obj.items():
|
|
308
|
+
path = f"{prefix}.{key}" if prefix else key
|
|
309
|
+
jp = f"{json_path_prefix}.{key}" if json_path_prefix else key
|
|
310
|
+
if isinstance(value, str) and value.strip():
|
|
311
|
+
fields.append({"path": path, "jsonPath": jp, "value": value})
|
|
312
|
+
elif isinstance(value, dict):
|
|
313
|
+
fields.extend(collect_string_fields(value, path, jp))
|
|
314
|
+
return fields
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
def _bundle_items(deployed: dict[str, Any], project: dict[str, Any]) -> list[dict[str, Any]]:
|
|
318
|
+
items: list[dict[str, Any]] = []
|
|
319
|
+
seen: set[str] = set()
|
|
320
|
+
for target in (deployed.get("targets") or {}).values():
|
|
321
|
+
for name, state in (((target or {}).get("resources") or {}).get("configBundles") or {}).items():
|
|
322
|
+
if name in seen:
|
|
323
|
+
continue
|
|
324
|
+
seen.add(name)
|
|
325
|
+
spec = next((b for b in project.get("configBundles") or [] if b["name"] == name), None)
|
|
326
|
+
items.append(
|
|
327
|
+
{
|
|
328
|
+
"name": name,
|
|
329
|
+
"bundleArn": state["bundleArn"],
|
|
330
|
+
"versionId": state.get("versionId"),
|
|
331
|
+
"fields": collect_string_fields((spec or {}).get("components"), "", "$") if spec else [],
|
|
332
|
+
}
|
|
333
|
+
)
|
|
334
|
+
return items
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
def _field_title(path: str) -> str:
|
|
338
|
+
segments = path.split(".")
|
|
339
|
+
if "configuration" in segments:
|
|
340
|
+
return ".".join(segments[segments.index("configuration") :])
|
|
341
|
+
return ".".join(segments[-2:])
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
def run_recommendation_wizard() -> None:
|
|
345
|
+
_require_creds()
|
|
346
|
+
config_io = ConfigIO()
|
|
347
|
+
region = _region.detect_region().region
|
|
348
|
+
deployed = to_jsonable(config_io.read_deployed_state())
|
|
349
|
+
agents: dict[str, dict[str, Any]] = {}
|
|
350
|
+
for target in (deployed.get("targets") or {}).values():
|
|
351
|
+
for name, state in (((target or {}).get("resources") or {}).get("runtimes") or {}).items():
|
|
352
|
+
agents.setdefault(name, state)
|
|
353
|
+
if not agents:
|
|
354
|
+
_error("No deployed agents found. Run `agentcore deploy` first.")
|
|
355
|
+
evaluators = control.list_evaluators(region=region)["evaluators"]
|
|
356
|
+
project = to_jsonable(config_io.read_project_spec())
|
|
357
|
+
bundles = _bundle_items(deployed, project)
|
|
358
|
+
|
|
359
|
+
rec_type = interactive.select(
|
|
360
|
+
"What do you want to optimize?",
|
|
361
|
+
[
|
|
362
|
+
Choice(
|
|
363
|
+
"System Prompt", "SYSTEM_PROMPT_RECOMMENDATION", "Optimize your agent's system prompt based on traces"
|
|
364
|
+
),
|
|
365
|
+
Choice(
|
|
366
|
+
"Tool Description",
|
|
367
|
+
"TOOL_DESCRIPTION_RECOMMENDATION",
|
|
368
|
+
"Optimize tool descriptions for better tool selection",
|
|
369
|
+
),
|
|
370
|
+
],
|
|
371
|
+
)
|
|
372
|
+
is_sys = rec_type == "SYSTEM_PROMPT_RECOMMENDATION"
|
|
373
|
+
agent = interactive.select("Select agent", [Choice(n, n, f"Runtime: {s['runtimeId']}") for n, s in agents.items()])
|
|
374
|
+
chosen_evaluators: list[str] = []
|
|
375
|
+
if is_sys:
|
|
376
|
+
chosen_evaluators = [
|
|
377
|
+
interactive.select(
|
|
378
|
+
"Select evaluator",
|
|
379
|
+
[
|
|
380
|
+
Choice(
|
|
381
|
+
e["evaluatorName"],
|
|
382
|
+
e["evaluatorArn"] or e["evaluatorName"],
|
|
383
|
+
e.get("description") or e.get("evaluatorType"),
|
|
384
|
+
)
|
|
385
|
+
for e in evaluators
|
|
386
|
+
],
|
|
387
|
+
)
|
|
388
|
+
]
|
|
389
|
+
input_choices = (
|
|
390
|
+
[
|
|
391
|
+
Choice("Enter inline", "inline", "Type or paste content directly"),
|
|
392
|
+
Choice("Load from file", "file", "Read content from a file path"),
|
|
393
|
+
Choice("Config bundle", "config-bundle", "Use system prompt from a deployed config bundle"),
|
|
394
|
+
]
|
|
395
|
+
if is_sys
|
|
396
|
+
else [
|
|
397
|
+
Choice("Enter inline", "inline", "Type tool name:description pairs directly"),
|
|
398
|
+
Choice("Config bundle", "config-bundle", "Read tool descriptions from a deployed config bundle"),
|
|
399
|
+
]
|
|
400
|
+
)
|
|
401
|
+
input_source = interactive.select(
|
|
402
|
+
"How do you want to provide the system prompt?" if is_sys else "How do you want to provide tool descriptions?",
|
|
403
|
+
input_choices,
|
|
404
|
+
)
|
|
405
|
+
content = tools = ""
|
|
406
|
+
bundle_arn = bundle_version = prompt_path = None
|
|
407
|
+
tool_paths: list[dict[str, str]] = []
|
|
408
|
+
if input_source == "config-bundle":
|
|
409
|
+
if not bundles:
|
|
410
|
+
_error("No deployed config bundles found. Run `agentcore add config-bundle` and `agentcore deploy` first.")
|
|
411
|
+
bundle_arn = interactive.select(
|
|
412
|
+
"Select config bundle", [Choice(b["name"], b["bundleArn"], b.get("versionId")) for b in bundles]
|
|
413
|
+
)
|
|
414
|
+
bundle = next(b for b in bundles if b["bundleArn"] == bundle_arn)
|
|
415
|
+
bundle_version = bundle.get("versionId")
|
|
416
|
+
fields = bundle["fields"]
|
|
417
|
+
if not fields:
|
|
418
|
+
_error("No text fields found in this config bundle's configuration.")
|
|
419
|
+
field_choices = [
|
|
420
|
+
Choice(_field_title(f["path"]), f["path"], f["value"][:80] + "…" if len(f["value"]) > 80 else f["value"])
|
|
421
|
+
for f in fields
|
|
422
|
+
]
|
|
423
|
+
if is_sys:
|
|
424
|
+
picked = interactive.select("Which field contains the system prompt?", field_choices)
|
|
425
|
+
prompt_path = next(f["jsonPath"] for f in fields if f["path"] == picked)
|
|
426
|
+
else:
|
|
427
|
+
if len(fields) == 1:
|
|
428
|
+
picked_paths = [interactive.select("Which field contains the tool description?", field_choices)]
|
|
429
|
+
else:
|
|
430
|
+
picked_paths = []
|
|
431
|
+
while not picked_paths:
|
|
432
|
+
picked_paths = interactive.checkbox("Which fields contain tool descriptions?", field_choices)
|
|
433
|
+
tool_paths = [
|
|
434
|
+
{"toolName": f["path"].split(".")[-1], "toolDescriptionJsonPath": f["jsonPath"]}
|
|
435
|
+
for f in fields
|
|
436
|
+
if f["path"] in picked_paths
|
|
437
|
+
]
|
|
438
|
+
elif is_sys and input_source == "file":
|
|
439
|
+
content = interactive.text(
|
|
440
|
+
"/path/to/prompt.txt",
|
|
441
|
+
validate=lambda v: None if os.path.isfile(os.path.expanduser(v)) else "File not found",
|
|
442
|
+
)
|
|
443
|
+
content = os.path.abspath(os.path.expanduser(content))
|
|
444
|
+
elif is_sys:
|
|
445
|
+
content = interactive.text("System prompt")
|
|
446
|
+
else:
|
|
447
|
+
typer.echo("Enter tool names and descriptions as comma-separated toolName:description pairs.")
|
|
448
|
+
tools = interactive.text("Tools")
|
|
449
|
+
|
|
450
|
+
trace_source = interactive.select(
|
|
451
|
+
"How do you want to source agent traces?",
|
|
452
|
+
[
|
|
453
|
+
Choice("CloudWatch Logs", "cloudwatch", "Discover traces from agent runtime logs"),
|
|
454
|
+
Choice("Session IDs", "sessions", "Provide specific session IDs manually"),
|
|
455
|
+
],
|
|
456
|
+
)
|
|
457
|
+
days = (
|
|
458
|
+
parse_int(
|
|
459
|
+
interactive.text("Lookback window (days)", default=str(DEFAULT_LOOKBACK_DAYS), validate=_validate_days)
|
|
460
|
+
)
|
|
461
|
+
or DEFAULT_LOOKBACK_DAYS
|
|
462
|
+
)
|
|
463
|
+
session_ids: list[str] = []
|
|
464
|
+
if trace_source == "sessions":
|
|
465
|
+
session_ids = _pick_sessions(agents[agent]["runtimeId"], region, days, "Select sessions to analyze")
|
|
466
|
+
kms = interactive.text("KMS key ARN for encryption (optional, press Enter to skip)", validate=_validate_kms)
|
|
467
|
+
|
|
468
|
+
rows = [("Type", "System Prompt" if is_sys else "Tool Description"), ("Agent", agent)]
|
|
469
|
+
if chosen_evaluators:
|
|
470
|
+
rows.append(("Evaluator", chosen_evaluators[0]))
|
|
471
|
+
rows += [("Source", input_source), ("Traces", trace_source), ("Lookback", f"{days} days")]
|
|
472
|
+
if kms:
|
|
473
|
+
rows.append(("KMS Key", kms))
|
|
474
|
+
for label, value in rows:
|
|
475
|
+
typer.echo(f" {label}: {value}")
|
|
476
|
+
if not interactive.confirm("Start recommendation?", default=True):
|
|
477
|
+
typer.echo("Cancelled.")
|
|
478
|
+
return
|
|
479
|
+
|
|
480
|
+
engine = create_job_engine(config_io)
|
|
481
|
+
result = engine.start(
|
|
482
|
+
"recommendation",
|
|
483
|
+
{
|
|
484
|
+
"type": rec_type,
|
|
485
|
+
"agent": agent,
|
|
486
|
+
"evaluators": chosen_evaluators,
|
|
487
|
+
"inputSource": input_source,
|
|
488
|
+
"inlineContent": content if input_source == "inline" else None,
|
|
489
|
+
"promptFile": content if input_source == "file" else None,
|
|
490
|
+
"bundleName": bundle_arn,
|
|
491
|
+
"bundleVersion": bundle_version,
|
|
492
|
+
"systemPromptJsonPath": prompt_path,
|
|
493
|
+
"toolDescJsonPaths": tool_paths or None,
|
|
494
|
+
"tools": [t.strip() for t in re.split(r",(?=[a-zA-Z0-9_\-.]+:)", tools) if t.strip()] if tools else None,
|
|
495
|
+
"traceSource": trace_source,
|
|
496
|
+
"lookbackDays": days,
|
|
497
|
+
"sessionIds": session_ids or None,
|
|
498
|
+
"kmsKeyArn": kms or None,
|
|
499
|
+
},
|
|
500
|
+
)
|
|
501
|
+
if not result.success:
|
|
502
|
+
_error("Recommendation failed", str(result.error))
|
|
503
|
+
record = result.value
|
|
504
|
+
typer.secho(f"✓ {record['id']} ({record['status']})", fg=typer.colors.GREEN)
|
|
505
|
+
typer.echo(
|
|
506
|
+
"When it completes, view it in Recommendation Jobs — the new config bundle (if any) will be applied to "
|
|
507
|
+
"agentcore.json automatically."
|
|
508
|
+
)
|
|
509
|
+
typer.echo(f"Next: agentcore view recommendation {record['id']}")
|
|
510
|
+
|
|
511
|
+
|
|
512
|
+
# ──────────────────────────────────────────────────────────────────────────────
|
|
513
|
+
# A/B test
|
|
514
|
+
# ──────────────────────────────────────────────────────────────────────────────
|
|
515
|
+
|
|
516
|
+
|
|
517
|
+
def _load_ab_resources() -> dict[str, Any]:
|
|
518
|
+
config_io = ConfigIO()
|
|
519
|
+
project = to_jsonable(config_io.read_project_spec())
|
|
520
|
+
deployed = to_jsonable(config_io.read_deployed_state())
|
|
521
|
+
bundles: list[str] = []
|
|
522
|
+
gateways: dict[str, None] = {}
|
|
523
|
+
evals: dict[str, None] = {}
|
|
524
|
+
for target in (deployed.get("targets") or {}).values():
|
|
525
|
+
resources = (target or {}).get("resources") or {}
|
|
526
|
+
bundles += list((resources.get("configBundles") or {}).keys())
|
|
527
|
+
gateways.update(dict.fromkeys(((resources.get("mcp") or {}).get("gateways") or {}).keys()))
|
|
528
|
+
gateways.update(dict.fromkeys((resources.get("gateways") or {}).keys()))
|
|
529
|
+
evals.update(dict.fromkeys((resources.get("onlineEvalConfigs") or {}).keys()))
|
|
530
|
+
targets: dict[str, None] = {}
|
|
531
|
+
for gw in project.get("agentCoreGateways") or []:
|
|
532
|
+
for t in gw.get("targets") or []:
|
|
533
|
+
if t.get("targetType") == "httpRuntime":
|
|
534
|
+
targets[t["name"]] = None
|
|
535
|
+
return {"gateways": list(gateways), "bundles": bundles, "targets": list(targets), "onlineEvalConfigs": list(evals)}
|
|
536
|
+
|
|
537
|
+
|
|
538
|
+
def _variant(variant: str, mode: str, resources: dict[str, Any], default_weight: int) -> dict[str, Any]:
|
|
539
|
+
typer.echo(f"{variant} Variant")
|
|
540
|
+
typer.echo("─" * 30)
|
|
541
|
+
out: dict[str, Any] = {}
|
|
542
|
+
if mode == "config-bundle":
|
|
543
|
+
out["bundle"] = interactive.select("Select config bundle:", [Choice(b, b) for b in resources["bundles"]])
|
|
544
|
+
typer.echo("Bundle version (or LATEST):")
|
|
545
|
+
out["version"] = interactive.text("Version", default="LATEST") or "LATEST"
|
|
546
|
+
else:
|
|
547
|
+
out["target"] = interactive.select("Select gateway target:", [Choice(t, t) for t in resources["targets"]])
|
|
548
|
+
out["eval"] = interactive.select(
|
|
549
|
+
"Select online eval (scoped to this endpoint):", [Choice(c, c) for c in resources["onlineEvalConfigs"]]
|
|
550
|
+
)
|
|
551
|
+
typer.echo("Traffic weight (0-100):")
|
|
552
|
+
out["weight"] = parse_int(
|
|
553
|
+
interactive.text(
|
|
554
|
+
"Weight",
|
|
555
|
+
default=str(default_weight),
|
|
556
|
+
validate=lambda v: (
|
|
557
|
+
None if (w := parse_int(v)) is not None and 0 <= w <= 100 else "Must be between 0 and 100"
|
|
558
|
+
),
|
|
559
|
+
)
|
|
560
|
+
)
|
|
561
|
+
return out
|
|
562
|
+
|
|
563
|
+
|
|
564
|
+
def run_ab_test_wizard() -> None:
|
|
565
|
+
_require_creds()
|
|
566
|
+
resources = _load_ab_resources()
|
|
567
|
+
if not resources["gateways"]:
|
|
568
|
+
_error("No deployed gateway found. Run `agentcore add gateway` and `agentcore deploy` first.")
|
|
569
|
+
mode = interactive.select(
|
|
570
|
+
"Variant mode",
|
|
571
|
+
[
|
|
572
|
+
Choice("Config bundle", "config-bundle", "Compare two configuration bundle versions"),
|
|
573
|
+
Choice("Target based", "target-based", "Compare two gateway-target runtime endpoints"),
|
|
574
|
+
],
|
|
575
|
+
)
|
|
576
|
+
gateway = interactive.select("Select gateway", [Choice(g, g) for g in resources["gateways"]])
|
|
577
|
+
control_v = _variant("Control", mode, resources, 50)
|
|
578
|
+
treatment_v = _variant("Treatment", mode, resources, 100 - (control_v["weight"] or 50))
|
|
579
|
+
treatment_weight = treatment_v["weight"] or 0
|
|
580
|
+
control_weight = 100 - treatment_weight
|
|
581
|
+
online_eval = None
|
|
582
|
+
if mode == "config-bundle":
|
|
583
|
+
online_eval = interactive.select(
|
|
584
|
+
"Shared online eval config", [Choice(c, c) for c in resources["onlineEvalConfigs"]]
|
|
585
|
+
)
|
|
586
|
+
typer.echo("Gateway filter (optional)")
|
|
587
|
+
typer.echo('Restrict the test to one gateway target path pattern (e.g. "/orders/*").')
|
|
588
|
+
typer.echo("Leave blank to have no gateway filter.")
|
|
589
|
+
gateway_filter = interactive.text("Gateway filter").strip()
|
|
590
|
+
typer.echo("A short name for this A/B test.")
|
|
591
|
+
name = interactive.text("A/B test name", validate=lambda v: None if v.strip() else "Name is required").strip()
|
|
592
|
+
|
|
593
|
+
rows = [("Name", name), ("Mode", mode), ("Gateway", gateway)]
|
|
594
|
+
if mode == "config-bundle":
|
|
595
|
+
rows += [
|
|
596
|
+
("Control", f"{control_v['bundle']} @ {control_v['version']} (weight {control_weight})"),
|
|
597
|
+
("Treatment", f"{treatment_v['bundle']} @ {treatment_v['version']} (weight {treatment_weight})"),
|
|
598
|
+
("Online eval", online_eval or ""),
|
|
599
|
+
]
|
|
600
|
+
else:
|
|
601
|
+
rows += [
|
|
602
|
+
("Control", f"{control_v['target']} — eval: {control_v['eval']} (weight {control_weight})"),
|
|
603
|
+
("Treatment", f"{treatment_v['target']} — eval: {treatment_v['eval']} (weight {treatment_weight})"),
|
|
604
|
+
]
|
|
605
|
+
rows.append(("Gateway filter", gateway_filter or "none"))
|
|
606
|
+
for label, value in rows:
|
|
607
|
+
typer.echo(f" {label}: {value}")
|
|
608
|
+
if not interactive.confirm("Start A/B test?", default=True):
|
|
609
|
+
typer.echo("Cancelled.")
|
|
610
|
+
return
|
|
611
|
+
cb = mode == "config-bundle"
|
|
612
|
+
engine = create_job_engine(ConfigIO())
|
|
613
|
+
result = engine.start(
|
|
614
|
+
"ab-test",
|
|
615
|
+
{
|
|
616
|
+
"name": name,
|
|
617
|
+
"mode": mode,
|
|
618
|
+
"gateway": gateway,
|
|
619
|
+
"controlBundle": control_v.get("bundle") if cb else None,
|
|
620
|
+
"controlVersion": control_v.get("version") if cb else None,
|
|
621
|
+
"treatmentBundle": treatment_v.get("bundle") if cb else None,
|
|
622
|
+
"treatmentVersion": treatment_v.get("version") if cb else None,
|
|
623
|
+
"controlTarget": None if cb else control_v.get("target"),
|
|
624
|
+
"treatmentTarget": None if cb else treatment_v.get("target"),
|
|
625
|
+
"onlineEval": online_eval if cb else None,
|
|
626
|
+
"controlOnlineEval": None if cb else control_v.get("eval"),
|
|
627
|
+
"treatmentOnlineEval": None if cb else treatment_v.get("eval"),
|
|
628
|
+
"gatewayFilter": gateway_filter or None,
|
|
629
|
+
"controlWeight": control_weight,
|
|
630
|
+
"treatmentWeight": treatment_weight,
|
|
631
|
+
"enableOnCreate": True,
|
|
632
|
+
"onProgress": lambda _s, m: typer.echo(m),
|
|
633
|
+
},
|
|
634
|
+
)
|
|
635
|
+
if not result.success:
|
|
636
|
+
_error("A/B test failed", str(result.error))
|
|
637
|
+
record = result.value
|
|
638
|
+
typer.secho(f"✓ {record['id']} ({record['status']})", fg=typer.colors.GREEN)
|
|
639
|
+
typer.echo(f"Next: agentcore view ab-test {record['id']}")
|