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.
Files changed (655) hide show
  1. agentcore/__init__.py +1 -0
  2. agentcore/agent_inspector/NOTICE +9 -0
  3. agentcore/agent_inspector/favicon.svg +60 -0
  4. agentcore/agent_inspector/index.css +1 -0
  5. agentcore/agent_inspector/index.html +14 -0
  6. agentcore/agent_inspector/index.js +289 -0
  7. agentcore/assets/AGENTS.md +60 -0
  8. agentcore/assets/README.md +108 -0
  9. agentcore/assets/agents/AGENTS.md +218 -0
  10. agentcore/assets/cdk/.prettierrc +8 -0
  11. agentcore/assets/cdk/README.md +26 -0
  12. agentcore/assets/cdk/bin/cdk.ts +216 -0
  13. agentcore/assets/cdk/cdk.json +88 -0
  14. agentcore/assets/cdk/gitignore.template +9 -0
  15. agentcore/assets/cdk/jest.config.js +9 -0
  16. agentcore/assets/cdk/lib/cdk-stack.ts +291 -0
  17. agentcore/assets/cdk/npmignore.template +6 -0
  18. agentcore/assets/cdk/package.json +30 -0
  19. agentcore/assets/cdk/test/cdk.test.ts +31 -0
  20. agentcore/assets/cdk/tsconfig.json +28 -0
  21. agentcore/assets/container/python/Dockerfile +47 -0
  22. agentcore/assets/container/python/dockerignore.template +27 -0
  23. agentcore/assets/container/typescript/Dockerfile +25 -0
  24. agentcore/assets/container/typescript/dockerignore.template +24 -0
  25. agentcore/assets/datasets/predefined-v1.jsonl +3 -0
  26. agentcore/assets/datasets/simulated-v1.jsonl +3 -0
  27. agentcore/assets/evaluators/autoevals-lambda/execution-role-policy.json +15 -0
  28. agentcore/assets/evaluators/autoevals-lambda/lambda_function.py +37 -0
  29. agentcore/assets/evaluators/autoevals-lambda/pyproject.toml +22 -0
  30. agentcore/assets/evaluators/deepeval-lambda/execution-role-policy.json +15 -0
  31. agentcore/assets/evaluators/deepeval-lambda/lambda_function.py +29 -0
  32. agentcore/assets/evaluators/deepeval-lambda/pyproject.toml +19 -0
  33. agentcore/assets/evaluators/python-lambda/execution-role-policy.json +10 -0
  34. agentcore/assets/evaluators/python-lambda/lambda_function.py +19 -0
  35. agentcore/assets/evaluators/python-lambda/pyproject.toml +15 -0
  36. agentcore/assets/harness/invoke.py.template +74 -0
  37. agentcore/assets/mcp/python/README.md +27 -0
  38. agentcore/assets/mcp/python/pyproject.toml +22 -0
  39. agentcore/assets/mcp/python/server.py +117 -0
  40. agentcore/assets/mcp/python-lambda/README.md +22 -0
  41. agentcore/assets/mcp/python-lambda/handler.py +144 -0
  42. agentcore/assets/mcp/python-lambda/pyproject.toml +15 -0
  43. agentcore/assets/python/a2a/googleadk/base/README.md +22 -0
  44. agentcore/assets/python/a2a/googleadk/base/gitignore.template +41 -0
  45. agentcore/assets/python/a2a/googleadk/base/main.py +124 -0
  46. agentcore/assets/python/a2a/googleadk/base/model/__init__.py +1 -0
  47. agentcore/assets/python/a2a/googleadk/base/model/load.py +41 -0
  48. agentcore/assets/python/a2a/googleadk/base/pyproject.toml +22 -0
  49. agentcore/assets/python/a2a/langchain_langgraph/base/README.md +22 -0
  50. agentcore/assets/python/a2a/langchain_langgraph/base/gitignore.template +41 -0
  51. agentcore/assets/python/a2a/langchain_langgraph/base/main.py +144 -0
  52. agentcore/assets/python/a2a/langchain_langgraph/base/model/__init__.py +1 -0
  53. agentcore/assets/python/a2a/langchain_langgraph/base/model/load.py +123 -0
  54. agentcore/assets/python/a2a/langchain_langgraph/base/pyproject.toml +26 -0
  55. agentcore/assets/python/a2a/strands/base/README.md +22 -0
  56. agentcore/assets/python/a2a/strands/base/gitignore.template +41 -0
  57. agentcore/assets/python/a2a/strands/base/main.py +113 -0
  58. agentcore/assets/python/a2a/strands/base/model/__init__.py +1 -0
  59. agentcore/assets/python/a2a/strands/base/model/load.py +123 -0
  60. agentcore/assets/python/a2a/strands/base/pyproject.toml +23 -0
  61. agentcore/assets/python/a2a/strands/capabilities/memory/__init__.py +1 -0
  62. agentcore/assets/python/a2a/strands/capabilities/memory/session.py +46 -0
  63. agentcore/assets/python/agui/googleadk/base/README.md +30 -0
  64. agentcore/assets/python/agui/googleadk/base/gitignore.template +41 -0
  65. agentcore/assets/python/agui/googleadk/base/main.py +91 -0
  66. agentcore/assets/python/agui/googleadk/base/model/__init__.py +1 -0
  67. agentcore/assets/python/agui/googleadk/base/model/load.py +41 -0
  68. agentcore/assets/python/agui/googleadk/base/pyproject.toml +25 -0
  69. agentcore/assets/python/agui/langchain_langgraph/base/README.md +22 -0
  70. agentcore/assets/python/agui/langchain_langgraph/base/gitignore.template +41 -0
  71. agentcore/assets/python/agui/langchain_langgraph/base/main.py +130 -0
  72. agentcore/assets/python/agui/langchain_langgraph/base/model/__init__.py +1 -0
  73. agentcore/assets/python/agui/langchain_langgraph/base/model/load.py +123 -0
  74. agentcore/assets/python/agui/langchain_langgraph/base/pyproject.toml +31 -0
  75. agentcore/assets/python/agui/strands/base/README.md +22 -0
  76. agentcore/assets/python/agui/strands/base/gitignore.template +41 -0
  77. agentcore/assets/python/agui/strands/base/main.py +105 -0
  78. agentcore/assets/python/agui/strands/base/model/__init__.py +1 -0
  79. agentcore/assets/python/agui/strands/base/model/load.py +123 -0
  80. agentcore/assets/python/agui/strands/base/pyproject.toml +27 -0
  81. agentcore/assets/python/agui/strands/capabilities/memory/__init__.py +1 -0
  82. agentcore/assets/python/agui/strands/capabilities/memory/session.py +46 -0
  83. agentcore/assets/python/http/autogen/base/README.md +45 -0
  84. agentcore/assets/python/http/autogen/base/gitignore.template +41 -0
  85. agentcore/assets/python/http/autogen/base/main.py +145 -0
  86. agentcore/assets/python/http/autogen/base/mcp_client/__init__.py +1 -0
  87. agentcore/assets/python/http/autogen/base/mcp_client/client.py +28 -0
  88. agentcore/assets/python/http/autogen/base/model/__init__.py +1 -0
  89. agentcore/assets/python/http/autogen/base/model/load.py +136 -0
  90. agentcore/assets/python/http/autogen/base/pyproject.toml +34 -0
  91. agentcore/assets/python/http/bma/base/Dockerfile +41 -0
  92. agentcore/assets/python/http/bma/base/README.md +178 -0
  93. agentcore/assets/python/http/bma/base/client.py +200 -0
  94. agentcore/assets/python/http/bma/base/lifecycle/server.py +641 -0
  95. agentcore/assets/python/http/bma/base/otel/collector.yaml +69 -0
  96. agentcore/assets/python/http/bma/base/plugins/acr-report/.codex-plugin/plugin.json +6 -0
  97. agentcore/assets/python/http/bma/base/plugins/acr-report/skills/acr-report/SKILL.md +16 -0
  98. agentcore/assets/python/http/bma/base/policies/bma-acr-policy.json +11 -0
  99. agentcore/assets/python/http/bma/base/policies/bma-session-policy.json +35 -0
  100. agentcore/assets/python/http/bma/base/policies/bma-session-trust.json +20 -0
  101. agentcore/assets/python/http/bma/base/pyproject.toml +21 -0
  102. agentcore/assets/python/http/googleadk/base/README.md +45 -0
  103. agentcore/assets/python/http/googleadk/base/gitignore.template +41 -0
  104. agentcore/assets/python/http/googleadk/base/main.py +207 -0
  105. agentcore/assets/python/http/googleadk/base/mcp_client/__init__.py +1 -0
  106. agentcore/assets/python/http/googleadk/base/mcp_client/client.py +75 -0
  107. agentcore/assets/python/http/googleadk/base/model/__init__.py +1 -0
  108. agentcore/assets/python/http/googleadk/base/model/load.py +41 -0
  109. agentcore/assets/python/http/googleadk/base/pyproject.toml +24 -0
  110. agentcore/assets/python/http/langchain_langgraph/base/README.md +45 -0
  111. agentcore/assets/python/http/langchain_langgraph/base/gitignore.template +41 -0
  112. agentcore/assets/python/http/langchain_langgraph/base/main.py +227 -0
  113. agentcore/assets/python/http/langchain_langgraph/base/mcp_client/__init__.py +1 -0
  114. agentcore/assets/python/http/langchain_langgraph/base/mcp_client/client.py +79 -0
  115. agentcore/assets/python/http/langchain_langgraph/base/model/__init__.py +1 -0
  116. agentcore/assets/python/http/langchain_langgraph/base/model/load.py +123 -0
  117. agentcore/assets/python/http/langchain_langgraph/base/pyproject.toml +38 -0
  118. agentcore/assets/python/http/openaiagents/base/README.md +45 -0
  119. agentcore/assets/python/http/openaiagents/base/gitignore.template +41 -0
  120. agentcore/assets/python/http/openaiagents/base/main.py +200 -0
  121. agentcore/assets/python/http/openaiagents/base/mcp_client/__init__.py +1 -0
  122. agentcore/assets/python/http/openaiagents/base/mcp_client/client.py +74 -0
  123. agentcore/assets/python/http/openaiagents/base/model/__init__.py +1 -0
  124. agentcore/assets/python/http/openaiagents/base/model/load.py +37 -0
  125. agentcore/assets/python/http/openaiagents/base/pyproject.toml +21 -0
  126. agentcore/assets/python/http/strands/base/README.md +46 -0
  127. agentcore/assets/python/http/strands/base/gitignore.template +41 -0
  128. agentcore/assets/python/http/strands/base/main.py +714 -0
  129. agentcore/assets/python/http/strands/base/mcp_client/__init__.py +1 -0
  130. agentcore/assets/python/http/strands/base/mcp_client/client.py +116 -0
  131. agentcore/assets/python/http/strands/base/model/__init__.py +1 -0
  132. agentcore/assets/python/http/strands/base/model/load.py +239 -0
  133. agentcore/assets/python/http/strands/base/model/mantle_compat.py +21 -0
  134. agentcore/assets/python/http/strands/base/pyproject.toml +31 -0
  135. agentcore/assets/python/http/strands/base/skills/fetcher.py +279 -0
  136. agentcore/assets/python/http/strands/capabilities/execution-limits/hooks/execution_limits.py +54 -0
  137. agentcore/assets/python/http/strands/capabilities/memory/__init__.py +1 -0
  138. agentcore/assets/python/http/strands/capabilities/memory/session.py +47 -0
  139. agentcore/assets/python/http/strands/capabilities/payments/__init__.py +4 -0
  140. agentcore/assets/python/http/strands/capabilities/payments/payments.py +142 -0
  141. agentcore/assets/python/mcp/standalone/base/README.md +36 -0
  142. agentcore/assets/python/mcp/standalone/base/gitignore.template +41 -0
  143. agentcore/assets/python/mcp/standalone/base/main.py +83 -0
  144. agentcore/assets/python/mcp/standalone/base/pyproject.toml +16 -0
  145. agentcore/assets/typescript/.gitkeep +0 -0
  146. agentcore/assets/typescript/http/strands/base/README.md +42 -0
  147. agentcore/assets/typescript/http/strands/base/gitignore.template +22 -0
  148. agentcore/assets/typescript/http/strands/base/main.ts +149 -0
  149. agentcore/assets/typescript/http/strands/base/mcp_client/client.ts +11 -0
  150. agentcore/assets/typescript/http/strands/base/model/load.ts +102 -0
  151. agentcore/assets/typescript/http/strands/base/package.json +38 -0
  152. agentcore/assets/typescript/http/strands/base/tsconfig.json +19 -0
  153. agentcore/assets/typescript/http/strands/capabilities/memory/memory.ts +52 -0
  154. agentcore/assets/typescript/http/vercelai/base/README.md +42 -0
  155. agentcore/assets/typescript/http/vercelai/base/gitignore.template +22 -0
  156. agentcore/assets/typescript/http/vercelai/base/main.ts +70 -0
  157. agentcore/assets/typescript/http/vercelai/base/model/load.ts +121 -0
  158. agentcore/assets/typescript/http/vercelai/base/package.json +35 -0
  159. agentcore/assets/typescript/http/vercelai/base/tsconfig.json +19 -0
  160. agentcore/aws/__init__.py +263 -0
  161. agentcore/aws/_aws_errors.py +72 -0
  162. agentcore/aws/_http.py +176 -0
  163. agentcore/aws/_util.py +37 -0
  164. agentcore/aws/account.py +165 -0
  165. agentcore/aws/agentcore.py +971 -0
  166. agentcore/aws/agentcore_ab_tests.py +230 -0
  167. agentcore/aws/agentcore_batch_evaluation.py +227 -0
  168. agentcore/aws/agentcore_config_bundles.py +220 -0
  169. agentcore/aws/agentcore_control.py +994 -0
  170. agentcore/aws/agentcore_datasets.py +222 -0
  171. agentcore/aws/agentcore_harness.py +330 -0
  172. agentcore/aws/agentcore_payments.py +430 -0
  173. agentcore/aws/agentcore_recommendation.py +140 -0
  174. agentcore/aws/agui_parser.py +131 -0
  175. agentcore/aws/agui_types.py +342 -0
  176. agentcore/aws/api_client.py +87 -0
  177. agentcore/aws/arn.py +18 -0
  178. agentcore/aws/aws_context.py +23 -0
  179. agentcore/aws/bedrock.py +44 -0
  180. agentcore/aws/bedrock_agent.py +129 -0
  181. agentcore/aws/bedrock_import.py +252 -0
  182. agentcore/aws/bedrock_import_types.py +111 -0
  183. agentcore/aws/cloudwatch.py +136 -0
  184. agentcore/aws/connect_shell.py +266 -0
  185. agentcore/aws/iam.py +41 -0
  186. agentcore/aws/partition.py +58 -0
  187. agentcore/aws/policy_generation.py +116 -0
  188. agentcore/aws/region.py +54 -0
  189. agentcore/aws/retry.py +27 -0
  190. agentcore/aws/shell_framer.py +136 -0
  191. agentcore/aws/stage_endpoint.py +39 -0
  192. agentcore/aws/target_region.py +54 -0
  193. agentcore/aws/transaction_search.py +97 -0
  194. agentcore/cdk/__init__.py +10 -0
  195. agentcore/cdk/constants.py +13 -0
  196. agentcore/cdk/local_cdk_project.py +48 -0
  197. agentcore/cdk/toolkit.py +706 -0
  198. agentcore/cli/__init__.py +0 -0
  199. agentcore/cli/commands/__init__.py +0 -0
  200. agentcore/cli/commands/_jobs_common.py +39 -0
  201. agentcore/cli/commands/_run_wizards.py +639 -0
  202. agentcore/cli/commands/add/__init__.py +37 -0
  203. agentcore/cli/commands/add/_commander.py +52 -0
  204. agentcore/cli/commands/add/_common.py +47 -0
  205. agentcore/cli/commands/add/agent_wizard.py +528 -0
  206. agentcore/cli/commands/add/auth_options.py +154 -0
  207. agentcore/cli/commands/add/skill_action.py +105 -0
  208. agentcore/cli/commands/add/skill_command.py +87 -0
  209. agentcore/cli/commands/add/tool_action.py +160 -0
  210. agentcore/cli/commands/add/tool_command.py +117 -0
  211. agentcore/cli/commands/add/validate.py +333 -0
  212. agentcore/cli/commands/capacity_provider/__init__.py +86 -0
  213. agentcore/cli/commands/capacity_provider/action.py +114 -0
  214. agentcore/cli/commands/capacity_provider/constants.py +22 -0
  215. agentcore/cli/commands/config.py +91 -0
  216. agentcore/cli/commands/config_bundle.py +251 -0
  217. agentcore/cli/commands/create/__init__.py +643 -0
  218. agentcore/cli/commands/create/action.py +406 -0
  219. agentcore/cli/commands/create/dependencies.py +91 -0
  220. agentcore/cli/commands/create/harness_validate.py +82 -0
  221. agentcore/cli/commands/create/validate.py +195 -0
  222. agentcore/cli/commands/create/wizard.py +127 -0
  223. agentcore/cli/commands/dataset.py +119 -0
  224. agentcore/cli/commands/deploy/__init__.py +31 -0
  225. agentcore/cli/commands/deploy/_guards.py +25 -0
  226. agentcore/cli/commands/deploy/actions.py +840 -0
  227. agentcore/cli/commands/deploy/command.py +349 -0
  228. agentcore/cli/commands/deploy/progress.py +115 -0
  229. agentcore/cli/commands/deploy/types.py +68 -0
  230. agentcore/cli/commands/deploy/utils.py +43 -0
  231. agentcore/cli/commands/deploy/validate.py +21 -0
  232. agentcore/cli/commands/dev/__init__.py +5 -0
  233. agentcore/cli/commands/dev/_deps.py +50 -0
  234. agentcore/cli/commands/dev/browser_mode.py +270 -0
  235. agentcore/cli/commands/dev/command.py +450 -0
  236. agentcore/cli/commands/dev/terminal_mode.py +379 -0
  237. agentcore/cli/commands/exec/__init__.py +29 -0
  238. agentcore/cli/commands/exec/action.py +442 -0
  239. agentcore/cli/commands/exec/command.py +206 -0
  240. agentcore/cli/commands/exec/types.py +35 -0
  241. agentcore/cli/commands/export/__init__.py +114 -0
  242. agentcore/cli/commands/export/constants.py +21 -0
  243. agentcore/cli/commands/export/fetch_harness_spec.py +234 -0
  244. agentcore/cli/commands/export/harness_action.py +385 -0
  245. agentcore/cli/commands/export/harness_mapper.py +868 -0
  246. agentcore/cli/commands/export/harness_resolver.py +95 -0
  247. agentcore/cli/commands/export/types.py +90 -0
  248. agentcore/cli/commands/export/wizard.py +97 -0
  249. agentcore/cli/commands/feedback/__init__.py +69 -0
  250. agentcore/cli/commands/feedback/action.py +30 -0
  251. agentcore/cli/commands/feedback/consent_prompt.py +35 -0
  252. agentcore/cli/commands/feedback/wizard.py +49 -0
  253. agentcore/cli/commands/fetch/__init__.py +69 -0
  254. agentcore/cli/commands/fetch/action.py +62 -0
  255. agentcore/cli/commands/help.py +65 -0
  256. agentcore/cli/commands/import_/__init__.py +167 -0
  257. agentcore/cli/commands/import_/_js.py +72 -0
  258. agentcore/cli/commands/import_/actions.py +457 -0
  259. agentcore/cli/commands/import_/constants.py +45 -0
  260. agentcore/cli/commands/import_/import_evaluator.py +140 -0
  261. agentcore/cli/commands/import_/import_gateway.py +520 -0
  262. agentcore/cli/commands/import_/import_memory.py +128 -0
  263. agentcore/cli/commands/import_/import_online_eval.py +165 -0
  264. agentcore/cli/commands/import_/import_pipeline.py +145 -0
  265. agentcore/cli/commands/import_/import_runtime.py +214 -0
  266. agentcore/cli/commands/import_/import_utils.py +410 -0
  267. agentcore/cli/commands/import_/phase1_update.py +110 -0
  268. agentcore/cli/commands/import_/phase2_import.py +206 -0
  269. agentcore/cli/commands/import_/resource_import.py +228 -0
  270. agentcore/cli/commands/import_/template_utils.py +148 -0
  271. agentcore/cli/commands/import_/types.py +150 -0
  272. agentcore/cli/commands/import_/yaml_parser.py +265 -0
  273. agentcore/cli/commands/init.py +196 -0
  274. agentcore/cli/commands/invoke/__init__.py +32 -0
  275. agentcore/cli/commands/invoke/_deps.py +73 -0
  276. agentcore/cli/commands/invoke/action.py +840 -0
  277. agentcore/cli/commands/invoke/command.py +490 -0
  278. agentcore/cli/commands/invoke/constants.py +40 -0
  279. agentcore/cli/commands/invoke/guards.py +23 -0
  280. agentcore/cli/commands/invoke/interactive.py +604 -0
  281. agentcore/cli/commands/invoke/resolve.py +149 -0
  282. agentcore/cli/commands/invoke/resolve_prompt.py +60 -0
  283. agentcore/cli/commands/invoke/types.py +61 -0
  284. agentcore/cli/commands/invoke/validate.py +33 -0
  285. agentcore/cli/commands/job_actions.py +239 -0
  286. agentcore/cli/commands/job_history.py +380 -0
  287. agentcore/cli/commands/logs/__init__.py +53 -0
  288. agentcore/cli/commands/logs/action.py +159 -0
  289. agentcore/cli/commands/logs/filter_pattern.py +17 -0
  290. agentcore/cli/commands/logs/guards.py +51 -0
  291. agentcore/cli/commands/logs_evals.py +42 -0
  292. agentcore/cli/commands/package.py +118 -0
  293. agentcore/cli/commands/remove/__init__.py +172 -0
  294. agentcore/cli/commands/remove/skill_command.py +131 -0
  295. agentcore/cli/commands/remove/tool_command.py +59 -0
  296. agentcore/cli/commands/run.py +808 -0
  297. agentcore/cli/commands/run_ingest.py +97 -0
  298. agentcore/cli/commands/shared/__init__.py +0 -0
  299. agentcore/cli/commands/shared/arn_utils.py +9 -0
  300. agentcore/cli/commands/shared/filesystem_utils.py +421 -0
  301. agentcore/cli/commands/shared/header_utils.py +87 -0
  302. agentcore/cli/commands/shared/indexed_key_parser.py +76 -0
  303. agentcore/cli/commands/shared/lifecycle_utils.py +72 -0
  304. agentcore/cli/commands/shared/region_utils.py +20 -0
  305. agentcore/cli/commands/shared/vpc_utils.py +99 -0
  306. agentcore/cli/commands/status/__init__.py +30 -0
  307. agentcore/cli/commands/status/_guards.py +25 -0
  308. agentcore/cli/commands/status/action.py +741 -0
  309. agentcore/cli/commands/status/command.py +321 -0
  310. agentcore/cli/commands/status/constants.py +36 -0
  311. agentcore/cli/commands/status/format_knowledge_base.py +111 -0
  312. agentcore/cli/commands/telemetry.py +79 -0
  313. agentcore/cli/commands/traces/__init__.py +155 -0
  314. agentcore/cli/commands/traces/action.py +123 -0
  315. agentcore/cli/commands/update/__init__.py +63 -0
  316. agentcore/cli/commands/update/action.py +164 -0
  317. agentcore/cli/commands/validate.py +165 -0
  318. agentcore/cli/constants.py +96 -0
  319. agentcore/cli/errors.py +118 -0
  320. agentcore/cli/external_requirements/__init__.py +67 -0
  321. agentcore/cli/external_requirements/checks.py +280 -0
  322. agentcore/cli/external_requirements/detect.py +55 -0
  323. agentcore/cli/external_requirements/versions.py +57 -0
  324. agentcore/cli/groups.py +23 -0
  325. agentcore/cli/interactive.py +85 -0
  326. agentcore/cli/main.py +137 -0
  327. agentcore/cli/naming.py +11 -0
  328. agentcore/cli/notices.py +42 -0
  329. agentcore/cli/project.py +34 -0
  330. agentcore/cli/run_command.py +27 -0
  331. agentcore/cli/tree.py +135 -0
  332. agentcore/cli/update_notifier.py +123 -0
  333. agentcore/cli/variadic.py +50 -0
  334. agentcore/cloudformation/__init__.py +84 -0
  335. agentcore/cloudformation/bootstrap.py +64 -0
  336. agentcore/cloudformation/logical_ids.py +37 -0
  337. agentcore/cloudformation/outputs.py +566 -0
  338. agentcore/cloudformation/stack_discovery.py +75 -0
  339. agentcore/cloudformation/stack_events.py +107 -0
  340. agentcore/cloudformation/stack_status.py +98 -0
  341. agentcore/cloudformation/types.py +44 -0
  342. agentcore/lib/__init__.py +68 -0
  343. agentcore/lib/constants.py +77 -0
  344. agentcore/lib/dependency_management/__init__.py +23 -0
  345. agentcore/lib/dependency_management/messages.py +92 -0
  346. agentcore/lib/dependency_management/plan.py +98 -0
  347. agentcore/lib/dependency_management/semver.py +137 -0
  348. agentcore/lib/dependency_management/sync.py +139 -0
  349. agentcore/lib/dependency_management/types.py +56 -0
  350. agentcore/lib/errors/__init__.py +5 -0
  351. agentcore/lib/errors/types.py +352 -0
  352. agentcore/lib/errors/validation.py +121 -0
  353. agentcore/lib/packaging/__init__.py +81 -0
  354. agentcore/lib/packaging/build_args.py +23 -0
  355. agentcore/lib/packaging/build_context.py +26 -0
  356. agentcore/lib/packaging/build_context_dockerignore.py +45 -0
  357. agentcore/lib/packaging/container.py +95 -0
  358. agentcore/lib/packaging/helpers.py +289 -0
  359. agentcore/lib/packaging/node.py +153 -0
  360. agentcore/lib/packaging/python.py +135 -0
  361. agentcore/lib/packaging/types.py +69 -0
  362. agentcore/lib/packaging/uv.py +45 -0
  363. agentcore/lib/result.py +104 -0
  364. agentcore/lib/schemas/__init__.py +1 -0
  365. agentcore/lib/schemas/io/__init__.py +27 -0
  366. agentcore/lib/schemas/io/config_io.py +458 -0
  367. agentcore/lib/schemas/io/global_config.py +239 -0
  368. agentcore/lib/schemas/io/path_resolver.py +132 -0
  369. agentcore/lib/secrets/__init__.py +18 -0
  370. agentcore/lib/secrets/cipher.py +70 -0
  371. agentcore/lib/secrets/key_provider.py +163 -0
  372. agentcore/lib/secrets/sensitive_keys.py +55 -0
  373. agentcore/lib/time_constants.py +4 -0
  374. agentcore/lib/utils/__init__.py +47 -0
  375. agentcore/lib/utils/aws_account.py +15 -0
  376. agentcore/lib/utils/credentials.py +68 -0
  377. agentcore/lib/utils/dotenv.py +32 -0
  378. agentcore/lib/utils/env.py +105 -0
  379. agentcore/lib/utils/json_format.py +29 -0
  380. agentcore/lib/utils/json_rpc.py +22 -0
  381. agentcore/lib/utils/platform.py +33 -0
  382. agentcore/lib/utils/polling.py +86 -0
  383. agentcore/lib/utils/subprocess.py +135 -0
  384. agentcore/lib/utils/time_parser.py +48 -0
  385. agentcore/lib/utils/validation.py +106 -0
  386. agentcore/logging/__init__.py +10 -0
  387. agentcore/logging/_common.py +77 -0
  388. agentcore/logging/cdk_io_host.py +36 -0
  389. agentcore/logging/create_logger.py +107 -0
  390. agentcore/logging/dev_logger.py +63 -0
  391. agentcore/logging/exec_logger.py +159 -0
  392. agentcore/logging/invoke_logger.py +154 -0
  393. agentcore/logging/remove_logger.py +95 -0
  394. agentcore/operations/__init__.py +0 -0
  395. agentcore/operations/agent/__init__.py +0 -0
  396. agentcore/operations/agent/config_bundle_defaults.py +31 -0
  397. agentcore/operations/agent/generate/__init__.py +28 -0
  398. agentcore/operations/agent/generate/schema_mapper.py +319 -0
  399. agentcore/operations/agent/generate/types.py +172 -0
  400. agentcore/operations/agent/generate/write_agent_to_project.py +67 -0
  401. agentcore/operations/agent/import_/__init__.py +31 -0
  402. agentcore/operations/agent/import_/base_translator.py +449 -0
  403. agentcore/operations/agent/import_/constants.py +23 -0
  404. agentcore/operations/agent/import_/execute.py +127 -0
  405. agentcore/operations/agent/import_/langgraph_translator.py +294 -0
  406. agentcore/operations/agent/import_/pyproject_generator.py +73 -0
  407. agentcore/operations/agent/import_/strands_translator.py +289 -0
  408. agentcore/operations/config_bundle/__init__.py +1 -0
  409. agentcore/operations/config_bundle/bundle_name_variants.py +9 -0
  410. agentcore/operations/config_bundle/diff_versions.py +52 -0
  411. agentcore/operations/config_bundle/resolve_bundle.py +65 -0
  412. agentcore/operations/connectors/__init__.py +3 -0
  413. agentcore/operations/connectors/translators.py +63 -0
  414. agentcore/operations/dataset/__init__.py +21 -0
  415. agentcore/operations/dataset/delete.py +7 -0
  416. agentcore/operations/dataset/publish.py +16 -0
  417. agentcore/operations/dataset/pull.py +21 -0
  418. agentcore/operations/dataset/push.py +201 -0
  419. agentcore/operations/dataset/resolve_dataset.py +65 -0
  420. agentcore/operations/dataset/status.py +18 -0
  421. agentcore/operations/dataset/wait.py +25 -0
  422. agentcore/operations/deploy/__init__.py +152 -0
  423. agentcore/operations/deploy/backfill_vpc_id.py +90 -0
  424. agentcore/operations/deploy/change_detection.py +84 -0
  425. agentcore/operations/deploy/constants.py +58 -0
  426. agentcore/operations/deploy/dependency_sync.py +105 -0
  427. agentcore/operations/deploy/ensure_target.py +30 -0
  428. agentcore/operations/deploy/gateway_status.py +44 -0
  429. agentcore/operations/deploy/managed_memory_notice.py +36 -0
  430. agentcore/operations/deploy/payment_connector_authorization.py +106 -0
  431. agentcore/operations/deploy/post_deploy_datasets.py +96 -0
  432. agentcore/operations/deploy/post_deploy_knowledge_bases.py +104 -0
  433. agentcore/operations/deploy/post_deploy_observability.py +28 -0
  434. agentcore/operations/deploy/post_deploy_online_evals.py +60 -0
  435. agentcore/operations/deploy/pre_deploy_identity.py +505 -0
  436. agentcore/operations/deploy/preflight.py +385 -0
  437. agentcore/operations/deploy/region_override.py +45 -0
  438. agentcore/operations/deploy/teardown.py +153 -0
  439. agentcore/operations/dev/__init__.py +61 -0
  440. agentcore/operations/dev/_http.py +79 -0
  441. agentcore/operations/dev/_server.py +165 -0
  442. agentcore/operations/dev/codezip_dev_server.py +151 -0
  443. agentcore/operations/dev/config.py +128 -0
  444. agentcore/operations/dev/constants.py +9 -0
  445. agentcore/operations/dev/container_dev_server.py +237 -0
  446. agentcore/operations/dev/container_runtime.py +37 -0
  447. agentcore/operations/dev/dev_server.py +244 -0
  448. agentcore/operations/dev/gateway_env.py +25 -0
  449. agentcore/operations/dev/invoke.py +214 -0
  450. agentcore/operations/dev/invoke_a2a.py +204 -0
  451. agentcore/operations/dev/invoke_agui.py +88 -0
  452. agentcore/operations/dev/invoke_mcp.py +145 -0
  453. agentcore/operations/dev/invoke_types.py +30 -0
  454. agentcore/operations/dev/load_dev_env.py +26 -0
  455. agentcore/operations/dev/memory_env.py +19 -0
  456. agentcore/operations/dev/otel/__init__.py +5 -0
  457. agentcore/operations/dev/otel/collector.py +234 -0
  458. agentcore/operations/dev/otel/transforms.py +331 -0
  459. agentcore/operations/dev/payment_env.py +50 -0
  460. agentcore/operations/dev/server.py +28 -0
  461. agentcore/operations/dev/sse_transform.py +30 -0
  462. agentcore/operations/dev/utils.py +152 -0
  463. agentcore/operations/dev/web_ui/__init__.py +31 -0
  464. agentcore/operations/dev/web_ui/constants.py +25 -0
  465. agentcore/operations/dev/web_ui/handlers/__init__.py +36 -0
  466. agentcore/operations/dev/web_ui/handlers/_common.py +36 -0
  467. agentcore/operations/dev/web_ui/handlers/_deployed.py +37 -0
  468. agentcore/operations/dev/web_ui/handlers/a2a_proxy.py +37 -0
  469. agentcore/operations/dev/web_ui/handlers/cloudwatch_traces.py +71 -0
  470. agentcore/operations/dev/web_ui/handlers/harness_invocation.py +89 -0
  471. agentcore/operations/dev/web_ui/handlers/harness_utils.py +95 -0
  472. agentcore/operations/dev/web_ui/handlers/invocations.py +327 -0
  473. agentcore/operations/dev/web_ui/handlers/mcp_proxy.py +119 -0
  474. agentcore/operations/dev/web_ui/handlers/memory.py +84 -0
  475. agentcore/operations/dev/web_ui/handlers/resources.py +351 -0
  476. agentcore/operations/dev/web_ui/handlers/start.py +182 -0
  477. agentcore/operations/dev/web_ui/handlers/status.py +25 -0
  478. agentcore/operations/dev/web_ui/handlers/traces.py +50 -0
  479. agentcore/operations/dev/web_ui/run_web_ui.py +60 -0
  480. agentcore/operations/dev/web_ui/web_server.py +297 -0
  481. agentcore/operations/eval/__init__.py +8 -0
  482. agentcore/operations/eval/list_eval_runs.py +18 -0
  483. agentcore/operations/eval/logs_eval.py +119 -0
  484. agentcore/operations/eval/pause_resume.py +90 -0
  485. agentcore/operations/eval/run_eval.py +354 -0
  486. agentcore/operations/eval/shared/__init__.py +0 -0
  487. agentcore/operations/eval/shared/dataset_loader.py +68 -0
  488. agentcore/operations/eval/shared/dataset_session_provider.py +122 -0
  489. agentcore/operations/eval/shared/evaluator_runner.py +89 -0
  490. agentcore/operations/eval/shared/scenario_executor.py +71 -0
  491. agentcore/operations/eval/shared/span_collector.py +255 -0
  492. agentcore/operations/eval/storage.py +67 -0
  493. agentcore/operations/feedback/__init__.py +21 -0
  494. agentcore/operations/feedback/aperture_client.py +98 -0
  495. agentcore/operations/feedback/build_payload.py +97 -0
  496. agentcore/operations/feedback/constants.py +26 -0
  497. agentcore/operations/feedback/submit_feedback.py +150 -0
  498. agentcore/operations/fetch_access/__init__.py +36 -0
  499. agentcore/operations/fetch_access/_target.py +17 -0
  500. agentcore/operations/fetch_access/fetch_gateway_token.py +75 -0
  501. agentcore/operations/fetch_access/fetch_harness_token.py +72 -0
  502. agentcore/operations/fetch_access/fetch_runtime_token.py +76 -0
  503. agentcore/operations/fetch_access/list_agents.py +18 -0
  504. agentcore/operations/fetch_access/list_gateways.py +26 -0
  505. agentcore/operations/fetch_access/list_harnesses.py +23 -0
  506. agentcore/operations/fetch_access/oauth_token.py +162 -0
  507. agentcore/operations/fetch_access/types.py +34 -0
  508. agentcore/operations/harness/__init__.py +1 -0
  509. agentcore/operations/harness/orphan.py +84 -0
  510. agentcore/operations/harness/skill_utils.py +56 -0
  511. agentcore/operations/identity/__init__.py +33 -0
  512. agentcore/operations/identity/api_key_credential_provider.py +68 -0
  513. agentcore/operations/identity/oauth2_credential_provider.py +95 -0
  514. agentcore/operations/ingest/__init__.py +184 -0
  515. agentcore/operations/init/__init__.py +3 -0
  516. agentcore/operations/init/files.py +59 -0
  517. agentcore/operations/insights/__init__.py +21 -0
  518. agentcore/operations/insights/insights_storage.py +67 -0
  519. agentcore/operations/insights/run_insights.py +148 -0
  520. agentcore/operations/invoke/__init__.py +5 -0
  521. agentcore/operations/invoke/resolve_agent_context.py +85 -0
  522. agentcore/operations/jobs/__init__.py +38 -0
  523. agentcore/operations/jobs/ab_test/__init__.py +0 -0
  524. agentcore/operations/jobs/ab_test/build_options.py +126 -0
  525. agentcore/operations/jobs/ab_test/format.py +121 -0
  526. agentcore/operations/jobs/ab_test/handler.py +412 -0
  527. agentcore/operations/jobs/ab_test/promote.py +142 -0
  528. agentcore/operations/jobs/ab_test/resolve.py +221 -0
  529. agentcore/operations/jobs/batch_evaluation/__init__.py +0 -0
  530. agentcore/operations/jobs/batch_evaluation/build_source.py +68 -0
  531. agentcore/operations/jobs/batch_evaluation/dataset_phase1.py +95 -0
  532. agentcore/operations/jobs/batch_evaluation/format.py +58 -0
  533. agentcore/operations/jobs/batch_evaluation/handler.py +203 -0
  534. agentcore/operations/jobs/insights/__init__.py +0 -0
  535. agentcore/operations/jobs/insights/format.py +65 -0
  536. agentcore/operations/jobs/insights/handler.py +178 -0
  537. agentcore/operations/jobs/recommendation/__init__.py +0 -0
  538. agentcore/operations/jobs/recommendation/apply_to_bundle.py +76 -0
  539. agentcore/operations/jobs/recommendation/build_config.py +271 -0
  540. agentcore/operations/jobs/recommendation/fetch_session_spans.py +93 -0
  541. agentcore/operations/jobs/recommendation/format.py +77 -0
  542. agentcore/operations/jobs/recommendation/handler.py +331 -0
  543. agentcore/operations/jobs/shared/__init__.py +0 -0
  544. agentcore/operations/jobs/shared/constants.py +85 -0
  545. agentcore/operations/jobs/shared/engine.py +187 -0
  546. agentcore/operations/jobs/shared/format.py +104 -0
  547. agentcore/operations/jobs/shared/region.py +34 -0
  548. agentcore/operations/jobs/shared/resolve_agent_state.py +30 -0
  549. agentcore/operations/jobs/shared/storage.py +117 -0
  550. agentcore/operations/jobs/shared/wait.py +30 -0
  551. agentcore/operations/knowledge_base/__init__.py +33 -0
  552. agentcore/operations/knowledge_base/connector_config.py +105 -0
  553. agentcore/operations/knowledge_base/hydrate_data_sources.py +59 -0
  554. agentcore/operations/mcp/__init__.py +4 -0
  555. agentcore/operations/memory/__init__.py +13 -0
  556. agentcore/operations/memory/_records.py +72 -0
  557. agentcore/operations/memory/list_memory_records.py +45 -0
  558. agentcore/operations/memory/retrieve_memory_records.py +52 -0
  559. agentcore/operations/node/__init__.py +15 -0
  560. agentcore/operations/node/setup.py +36 -0
  561. agentcore/operations/python/__init__.py +17 -0
  562. agentcore/operations/python/setup.py +47 -0
  563. agentcore/operations/resolve_agent.py +159 -0
  564. agentcore/operations/session/__init__.py +86 -0
  565. agentcore/operations/traces/__init__.py +29 -0
  566. agentcore/operations/traces/get_trace.py +202 -0
  567. agentcore/operations/traces/insights_query.py +74 -0
  568. agentcore/operations/traces/list_traces.py +46 -0
  569. agentcore/operations/traces/trace_url.py +25 -0
  570. agentcore/operations/traces/types.py +55 -0
  571. agentcore/primitives/__init__.py +0 -0
  572. agentcore/primitives/_gateway_target_wizard.py +293 -0
  573. agentcore/primitives/_gateway_validation.py +442 -0
  574. agentcore/primitives/_harness_cli.py +557 -0
  575. agentcore/primitives/_harness_validation.py +163 -0
  576. agentcore/primitives/_harness_wizard.py +726 -0
  577. agentcore/primitives/_knowledge_base_wizard.py +259 -0
  578. agentcore/primitives/_payment_wizard.py +331 -0
  579. agentcore/primitives/_policy_form.py +160 -0
  580. agentcore/primitives/agent.py +817 -0
  581. agentcore/primitives/auth_utils.py +77 -0
  582. agentcore/primitives/base.py +178 -0
  583. agentcore/primitives/capacity_provider.py +501 -0
  584. agentcore/primitives/config_bundle.py +329 -0
  585. agentcore/primitives/credential.py +387 -0
  586. agentcore/primitives/credential_utils.py +45 -0
  587. agentcore/primitives/dataset.py +211 -0
  588. agentcore/primitives/deployed_gateways.py +34 -0
  589. agentcore/primitives/evaluator.py +909 -0
  590. agentcore/primitives/gateway.py +496 -0
  591. agentcore/primitives/gateway_target.py +988 -0
  592. agentcore/primitives/harness.py +706 -0
  593. agentcore/primitives/knowledge_base.py +477 -0
  594. agentcore/primitives/memory.py +387 -0
  595. agentcore/primitives/online_eval_config.py +365 -0
  596. agentcore/primitives/online_insights.py +275 -0
  597. agentcore/primitives/payment_connector.py +427 -0
  598. agentcore/primitives/payment_eligible.py +20 -0
  599. agentcore/primitives/payment_manager.py +605 -0
  600. agentcore/primitives/payment_validation.py +68 -0
  601. agentcore/primitives/policy.py +622 -0
  602. agentcore/primitives/policy_engine.py +358 -0
  603. agentcore/primitives/registry.py +56 -0
  604. agentcore/primitives/runtime_endpoint.py +361 -0
  605. agentcore/primitives/secret_flag_warning.py +17 -0
  606. agentcore/schema/__init__.py +14 -0
  607. agentcore/schema/_zod.py +395 -0
  608. agentcore/schema/constants.py +306 -0
  609. agentcore/schema/schemas/__init__.py +40 -0
  610. agentcore/schema/schemas/agent_env.py +545 -0
  611. agentcore/schema/schemas/agentcore_project.py +530 -0
  612. agentcore/schema/schemas/auth.py +286 -0
  613. agentcore/schema/schemas/aws_targets.py +72 -0
  614. agentcore/schema/schemas/connections.py +187 -0
  615. agentcore/schema/schemas/deployed_state.py +322 -0
  616. agentcore/schema/schemas/mcp.py +650 -0
  617. agentcore/schema/schemas/mcp_defs.py +54 -0
  618. agentcore/schema/schemas/primitives/__init__.py +52 -0
  619. agentcore/schema/schemas/primitives/ab_test.py +162 -0
  620. agentcore/schema/schemas/primitives/capacity_provider.py +214 -0
  621. agentcore/schema/schemas/primitives/config_bundle.py +48 -0
  622. agentcore/schema/schemas/primitives/dataset.py +55 -0
  623. agentcore/schema/schemas/primitives/evaluator.py +171 -0
  624. agentcore/schema/schemas/primitives/harness.py +710 -0
  625. agentcore/schema/schemas/primitives/knowledge_base.py +90 -0
  626. agentcore/schema/schemas/primitives/memory.py +113 -0
  627. agentcore/schema/schemas/primitives/online_eval_config.py +77 -0
  628. agentcore/schema/schemas/primitives/payment.py +114 -0
  629. agentcore/schema/schemas/primitives/policy.py +83 -0
  630. agentcore/schema/schemas/primitives/tags.py +50 -0
  631. agentcore/schema/schemas/zod_util.py +5 -0
  632. agentcore/schema/types/__init__.py +3 -0
  633. agentcore/schema/types/path.py +16 -0
  634. agentcore/templates/__init__.py +115 -0
  635. agentcore/templates/_handlebars.py +782 -0
  636. agentcore/templates/_js.py +164 -0
  637. agentcore/templates/base_renderer.py +107 -0
  638. agentcore/templates/cdk_renderer.py +129 -0
  639. agentcore/templates/evaluator_renderer.py +39 -0
  640. agentcore/templates/gateway_target_renderer.py +69 -0
  641. agentcore/templates/llm_context/README.md +16 -0
  642. agentcore/templates/llm_context/agentcore.ts +685 -0
  643. agentcore/templates/llm_context/aws-targets.ts +51 -0
  644. agentcore/templates/profiles.py +151 -0
  645. agentcore/templates/render.py +92 -0
  646. agentcore/templates/renderers.py +83 -0
  647. agentcore/templates/schema_assets.py +23 -0
  648. agentcore/templates/template_root.py +28 -0
  649. agentcore/templates/types.py +192 -0
  650. agentcore_cli-0.31.1.dist-info/METADATA +84 -0
  651. agentcore_cli-0.31.1.dist-info/RECORD +655 -0
  652. agentcore_cli-0.31.1.dist-info/WHEEL +4 -0
  653. agentcore_cli-0.31.1.dist-info/entry_points.txt +2 -0
  654. agentcore_cli-0.31.1.dist-info/licenses/LICENSE +175 -0
  655. agentcore_cli-0.31.1.dist-info/licenses/NOTICE +88 -0
@@ -0,0 +1,840 @@
1
+ """Deploy orchestration (port of ``commands/deploy/actions.ts``)."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ from collections.abc import Callable, Mapping
7
+ from dataclasses import dataclass
8
+ from typing import Any, Literal
9
+
10
+ from agentcore.aws.account import validate_aws_credentials
11
+ from agentcore.aws.target_region import apply_target_region_to_env
12
+ from agentcore.cdk.toolkit import (
13
+ CdkToolkitWrapper,
14
+ DeployMessage,
15
+ SwitchableIoHost,
16
+ create_switchable_io_host,
17
+ pattern_must_match,
18
+ )
19
+ from agentcore.cli.commands.deploy.types import DeployResult
20
+ from agentcore.cli.errors import get_error_message, is_changeset_in_progress_error, is_stack_in_progress_error
21
+ from agentcore.cloudformation import outputs as cfn_outputs
22
+ from agentcore.lib.dependency_management.types import DependencySyncResult
23
+ from agentcore.lib.errors.types import DependencySyncError, ResourceNotFoundError, ValidationError, to_error
24
+ from agentcore.lib.result import Err, Ok
25
+ from agentcore.lib.schemas.io.config_io import ConfigIO, to_jsonable
26
+ from agentcore.lib.utils.credentials import SecureCredentials
27
+ from agentcore.logging.exec_logger import ExecLogger
28
+ from agentcore.operations.deploy import (
29
+ backfill_vpc_id,
30
+ change_detection,
31
+ dependency_sync,
32
+ ensure_target,
33
+ gateway_status,
34
+ post_deploy_datasets,
35
+ post_deploy_knowledge_bases,
36
+ post_deploy_observability,
37
+ post_deploy_online_evals,
38
+ pre_deploy_identity,
39
+ preflight,
40
+ teardown,
41
+ )
42
+ from agentcore.operations.deploy import managed_memory_notice as memory_notice
43
+ from agentcore.operations.deploy import payment_connector_authorization as pca
44
+ from agentcore.operations.harness.orphan import find_orphan_harnesses
45
+ from agentcore.operations.knowledge_base.hydrate_data_sources import hydrate_knowledge_base_data_sources
46
+
47
+ StepStatus = Literal["start", "success", "error", "warn"]
48
+
49
+ AGENT_NEXT_STEPS = ["agentcore invoke", "agentcore status"]
50
+ MEMORY_ONLY_NEXT_STEPS = ["agentcore add agent", "agentcore status"]
51
+
52
+
53
+ @dataclass
54
+ class ValidatedDeployOptions:
55
+ target: str
56
+ auto_confirm: bool = False
57
+ verbose: bool = False
58
+ plan: bool = False
59
+ diff: bool = False
60
+ on_progress: Callable[[str, StepStatus], None] | None = None
61
+ on_resource_event: Callable[[str], None] | None = None
62
+ on_deploy_message: Callable[[DeployMessage], None] | None = None
63
+ # One-shot user-facing notice (e.g. managed-memory heads-up), always surfaced.
64
+ on_notice: Callable[[str], None] | None = None
65
+ # --- interactive-mode hooks (replace the Ink TUI's confirm/credential screens) ---
66
+ # Asked instead of failing when a teardown deploy runs without --yes.
67
+ confirm_teardown: Callable[[], bool] | None = None
68
+ # Asked instead of failing when bootstrap is needed without --yes; False skips bootstrapping.
69
+ confirm_bootstrap: Callable[[], bool] | None = None
70
+ # Credentials entered at the prompt (not persisted); override .env.local values.
71
+ runtime_credentials: SecureCredentials | None = None
72
+ # The prompt's "skip" choice: don't set up API key / OAuth providers.
73
+ skip_identity_setup: bool = False
74
+
75
+
76
+ def to_stack_name(project_name: str, target_name: str) -> str:
77
+ """Matches ``toStackName`` in the vended ``bin/cdk.ts`` (underscores -> dashes)."""
78
+ return f"AgentCore-{project_name.replace('_', '-')}-{target_name.replace('_', '-')}"
79
+
80
+
81
+ @dataclass(frozen=True)
82
+ class HarnessVersionDrift:
83
+ name: str
84
+ to: int
85
+ from_: int | None = None
86
+
87
+
88
+ def compute_harness_version_drift(
89
+ prev: Mapping[str, Any] | None, next_: Mapping[str, Mapping[str, Any]]
90
+ ) -> list[HarnessVersionDrift]:
91
+ """Harnesses whose (emitted) config version changed or appeared since the previous deploy."""
92
+
93
+ def version(record: Any) -> int | None:
94
+ if record is None:
95
+ return None
96
+ if isinstance(record, Mapping):
97
+ return record.get("harnessVersion")
98
+ return getattr(record, "harness_version", None)
99
+
100
+ notes = []
101
+ for name, record in next_.items():
102
+ to = version(record)
103
+ if to is None:
104
+ continue
105
+ frm = version((prev or {}).get(name))
106
+ if frm != to:
107
+ notes.append(HarnessVersionDrift(name=name, to=to, from_=frm))
108
+ return notes
109
+
110
+
111
+ def select_target_stack(stack_names: list[str], project_name: str, target_name: str) -> Ok[str] | Err[ValidationError]:
112
+ """The synthesized stack for the deployed target (never blindly ``stack_names[0]``)."""
113
+ if not stack_names:
114
+ return Err(ValidationError("No stacks found to deploy"))
115
+ expected = to_stack_name(project_name, target_name)
116
+ if expected not in stack_names:
117
+ return Err(
118
+ ValidationError(
119
+ f"Synthesized stacks [{', '.join(stack_names)}] do not include the stack for target "
120
+ f'"{target_name}" (expected "{expected}").'
121
+ )
122
+ )
123
+ return Ok(expected)
124
+
125
+
126
+ def run_diff(toolkit_wrapper: CdkToolkitWrapper, stack_name: str, io_host: SwitchableIoHost | None = None) -> None:
127
+ host = io_host or create_switchable_io_host()
128
+ has_content = False
129
+
130
+ def on_raw(code: str, _level: str, message: str, _data: Any = None) -> None:
131
+ nonlocal has_content
132
+ if not message:
133
+ return
134
+ # I4002: formatted diff per stack, I4001: overall diff summary
135
+ if code in ("CDK_TOOLKIT_I4002", "CDK_TOOLKIT_I4001"):
136
+ has_content = True
137
+ print(message)
138
+
139
+ host.set_on_raw_message(on_raw)
140
+ host.set_verbose(True)
141
+ if toolkit_wrapper.io_host is not host:
142
+ toolkit_wrapper.io_host = host
143
+ toolkit_wrapper.diff(pattern_must_match(stack_name))
144
+ if not has_content:
145
+ print("No stack differences detected.")
146
+ host.set_verbose(False)
147
+ host.set_on_raw_message(None)
148
+
149
+
150
+ def run_deploy(toolkit_wrapper: CdkToolkitWrapper, stack_name: str) -> None:
151
+ toolkit_wrapper.deploy(pattern_must_match(stack_name))
152
+
153
+
154
+ def _resources_json(state: Any, target_name: str) -> dict[str, Any]:
155
+ if state is None:
156
+ return {}
157
+ data = to_jsonable(state)
158
+ return ((data.get("targets") or {}).get(target_name) or {}).get("resources") or {}
159
+
160
+
161
+ def handle_deploy(options: ValidatedDeployOptions) -> DeployResult:
162
+ toolkit_wrapper: CdkToolkitWrapper | None = None
163
+ restore_env: Callable[[], None] | None = None
164
+ # Preview modes revert the vpcId backfill on every exit path (success, early return, or raise).
165
+ preview_restore: Callable[[], None] | None = None
166
+ logger = ExecLogger(command="deploy")
167
+ current_step = ""
168
+ sync_result: DependencySyncResult | None = None
169
+
170
+ def start_step(name: str) -> None:
171
+ nonlocal current_step
172
+ current_step = name
173
+ logger.start_step(name)
174
+ if options.on_progress:
175
+ options.on_progress(name, "start")
176
+
177
+ def end_step(status: Literal["success", "error", "warn"], message: str | None = None) -> None:
178
+ logger.end_step(status, message)
179
+ if options.on_progress:
180
+ options.on_progress(current_step, status)
181
+
182
+ def fail(error: BaseException) -> DeployResult:
183
+ logger.finalize(False)
184
+ return DeployResult(
185
+ success=False, error=error, log_path=logger.get_relative_log_path(), dependency_sync_result=sync_result
186
+ )
187
+
188
+ try:
189
+ config_io = ConfigIO()
190
+
191
+ # Fresh projects have an empty aws-targets.json; non-interactive deploys auto-populate one.
192
+ start_step("Load deployment target")
193
+ ensure_target.ensure_default_deployment_target(config_io)
194
+ targets = config_io.resolve_aws_deployment_targets()
195
+ target = next((t for t in targets if t.name == options.target), None)
196
+ if target is None:
197
+ end_step("error", f'Target "{options.target}" not found')
198
+ message = f'Target "{options.target}" not found in aws-targets.json'
199
+ if not targets:
200
+ # The default target is created from the detected AWS account; no account means no credentials.
201
+ message += (
202
+ ". No AWS account could be detected to create it: configure credentials "
203
+ "(e.g. `aws sso login --profile <name>` or `aws configure`) and try again."
204
+ )
205
+ return fail(ResourceNotFoundError(message))
206
+ # Make the target region authoritative for SDK and CDK calls (aws/agentcore-cli#924).
207
+ restore_env = apply_target_region_to_env(target.region)
208
+ end_step("success")
209
+
210
+ gateway_specs: list[Any] = []
211
+ try:
212
+ gateway_specs = list(config_io.read_project_spec().agent_core_gateways or [])
213
+ except Exception: # noqa: BLE001 - project read failed: no gateways
214
+ pass
215
+
216
+ start_step("Validate project")
217
+ context = preflight.validate_project(target)
218
+ end_step("success")
219
+ spec = context.project_spec
220
+
221
+ # Preview-build harnesses aren't CFN-managed; warn (skipped on teardown, which warns differently).
222
+ orphan_warnings: list[str] = []
223
+ if not context.is_teardown_deploy:
224
+ try:
225
+ pre_state = config_io.read_deployed_state()
226
+ except Exception: # noqa: BLE001
227
+ pre_state = None
228
+ for orphan in find_orphan_harnesses(pre_state):
229
+ warning = (
230
+ f'Harness "{orphan.name}" was created by the preview build and is not managed by '
231
+ "CloudFormation. This deploy won't touch it, and it keeps incurring cost. To migrate it "
232
+ f"to GA, run `agentcore remove harness {orphan.name} --keep` (deletes the old resource "
233
+ "but keeps it in agentcore.json), then deploy again so it's recreated under CloudFormation. "
234
+ "Use --discard instead if you no longer want it."
235
+ )
236
+ logger.log(warning, "warn")
237
+ orphan_warnings.append(warning)
238
+
239
+ if context.is_teardown_deploy and not options.auto_confirm:
240
+ if options.confirm_teardown is None or not options.confirm_teardown():
241
+ return fail(
242
+ ValidationError(
243
+ "This will delete all deployed resources and the CloudFormation stack. "
244
+ "Run with --yes to confirm teardown."
245
+ )
246
+ )
247
+
248
+ if context.is_teardown_deploy:
249
+ start_step("Validate AWS credentials")
250
+ validate_aws_credentials(target)
251
+ end_step("success")
252
+
253
+ # Pin agentcore/cdk/package.json. Previews are check-only; teardown never blocks on pinning.
254
+ is_preview = options.plan or options.diff
255
+ start_step(dependency_sync.SYNC_CDK_DEPENDENCIES_STEP)
256
+ try:
257
+ sync_result = dependency_sync.ensure_managed_dependencies(
258
+ context.cdk_project, check_only=is_preview, treat_skew_as_warning=context.is_teardown_deploy
259
+ )
260
+ except Exception as sync_err:
261
+ if not (context.is_teardown_deploy and isinstance(sync_err, DependencySyncError)):
262
+ sync_result = dependency_sync.failed_sync_result()
263
+ raise
264
+ sync_result = dependency_sync.teardown_sync_failure_result(sync_err)
265
+ for warning in sync_result.warnings:
266
+ logger.log(warning, "warn")
267
+ if sync_result.notice:
268
+ logger.log(sync_result.notice)
269
+ if options.on_notice:
270
+ options.on_notice(sync_result.notice)
271
+ end_step("warn" if sync_result.outcome == "failure-suppressed" else "success")
272
+
273
+ start_step("Build CDK project")
274
+ preflight.build_cdk_project(context.cdk_project)
275
+ end_step("success")
276
+
277
+ # Identity providers before synth (the CDK app reads credential ARNs from deployed state).
278
+ identity_kms_key_arn: str | None = None
279
+ env_check = pre_deploy_identity.assert_env_file_exists(spec, config_io.get_config_root())
280
+ if not env_check.success:
281
+ return fail(env_check.error)
282
+
283
+ # Runtime credentials from the process env (non-interactive deploy with -y).
284
+ env_credentials = {
285
+ c.env_var_name: os.environ[c.env_var_name]
286
+ for c in pre_deploy_identity.get_all_credentials(spec)
287
+ if os.environ.get(c.env_var_name)
288
+ }
289
+ runtime_credentials = SecureCredentials(env_credentials) if env_credentials else None
290
+ if options.runtime_credentials is not None:
291
+ runtime_credentials = (
292
+ runtime_credentials.merge(options.runtime_credentials)
293
+ if runtime_credentials
294
+ else options.runtime_credentials
295
+ )
296
+
297
+ deployed_credentials: dict[str, dict[str, Any]] = {}
298
+
299
+ if pre_deploy_identity.has_identity_api_providers(spec) and not options.skip_identity_setup:
300
+ start_step("Creating credentials...")
301
+ identity_result = pre_deploy_identity.setup_api_key_providers(
302
+ project_spec=spec,
303
+ config_base_dir=config_io.get_config_root(),
304
+ region=target.region,
305
+ runtime_credentials=runtime_credentials,
306
+ enable_kms_encryption=True,
307
+ )
308
+ if identity_result.has_errors:
309
+ failed = next((r for r in identity_result.results if r.status == "error" and r.error), None)
310
+ end_step("error", str(failed.error) if failed else "Identity setup failed")
311
+ return fail(
312
+ failed.error if failed else RuntimeError("unknown error occurred when setting up api key providers")
313
+ )
314
+ identity_kms_key_arn = identity_result.kms_key_arn
315
+ for r in identity_result.results:
316
+ if r.credential_provider_arn:
317
+ deployed_credentials[r.provider_name] = {"credentialProviderArn": r.credential_provider_arn}
318
+ end_step("success")
319
+
320
+ if pre_deploy_identity.has_identity_o_auth_providers(spec) and not options.skip_identity_setup:
321
+ start_step("Creating OAuth credentials...")
322
+ oauth_result = pre_deploy_identity.setup_o_auth2_providers(
323
+ project_spec=spec,
324
+ config_base_dir=config_io.get_config_root(),
325
+ region=target.region,
326
+ runtime_credentials=runtime_credentials,
327
+ )
328
+ if oauth_result.has_errors:
329
+ # Detailed error goes to the log; the step message is sanitized (no OAuth details).
330
+ failed_oauth = next((r for r in oauth_result.results if r.status == "error" and r.error), None)
331
+ logger.log(f"OAuth setup error: {failed_oauth.error if failed_oauth else 'unknown'}", "error")
332
+ end_step("error", "OAuth credential setup failed. Check the log for details.")
333
+ return fail(
334
+ failed_oauth.error
335
+ if failed_oauth
336
+ else RuntimeError("an unexpected error ocurred when setting up oauth providers")
337
+ )
338
+ for r in oauth_result.results:
339
+ if r.credential_provider_arn:
340
+ record: dict[str, Any] = {"credentialProviderArn": r.credential_provider_arn}
341
+ if r.client_secret_arn is not None:
342
+ record["clientSecretArn"] = r.client_secret_arn
343
+ if r.callback_url is not None:
344
+ record["callbackUrl"] = r.callback_url
345
+ deployed_credentials[r.provider_name] = record
346
+ end_step("success")
347
+
348
+ # Payment credential providers stay imperative; manager/connector/roles come from CDK.
349
+ if pre_deploy_identity.has_payment_credential_providers(spec):
350
+ start_step("Setting up payment credentials...")
351
+ payment_result = pre_deploy_identity.setup_payment_credential_providers(
352
+ project_spec=spec,
353
+ config_base_dir=config_io.get_config_root(),
354
+ region=target.region,
355
+ runtime_credentials=runtime_credentials,
356
+ )
357
+ if payment_result.has_errors:
358
+ messages = "; ".join(str(e) for e in payment_result.errors)
359
+ end_step("error", messages)
360
+ logger.log(f"Payment credential setup errors: {messages}", "error")
361
+ return fail(
362
+ payment_result.errors[0]
363
+ if payment_result.errors
364
+ else RuntimeError("payment deploy preflight steps failed")
365
+ )
366
+ for name, provider in payment_result.credential_providers.items():
367
+ deployed_credentials[name] = {"credentialProviderArn": provider.credential_provider_arn}
368
+ end_step("success")
369
+
370
+ # Credential ARNs go to deployed state before synth so the template can read them.
371
+ if deployed_credentials:
372
+ try:
373
+ existing_pre = to_jsonable(config_io.read_deployed_state())
374
+ except Exception: # noqa: BLE001
375
+ existing_pre = {"targets": {}}
376
+ target_state = (existing_pre.get("targets") or {}).get(target.name) or {"resources": {}}
377
+ resources = target_state.setdefault("resources", {}) or {}
378
+ target_state["resources"] = resources
379
+ resources["credentials"] = deployed_credentials
380
+ if identity_kms_key_arn:
381
+ resources["identityKmsKeyArn"] = identity_kms_key_arn
382
+ config_io.write_deployed_state(
383
+ {**existing_pre, "targets": {**(existing_pre.get("targets") or {}), target.name: target_state}}
384
+ )
385
+
386
+ # vpcId backfill for pre-existing Container+VPC configs (reverted after synth in previews).
387
+ backfill = backfill_vpc_id.backfill_container_vpc_ids(config_io, spec, target.region, not is_preview)
388
+ if is_preview:
389
+ preview_restore = backfill.restore
390
+ if backfill.backfilled:
391
+ logger.log(
392
+ f"Resolved networkConfig.vpcId for Container+VPC build(s): {', '.join(backfill.backfilled)}", "info"
393
+ )
394
+
395
+ start_step("Synthesize CloudFormation")
396
+ io_host = create_switchable_io_host() if (options.verbose or options.on_deploy_message) else None
397
+ synth_result = preflight.synthesize_cdk(context.cdk_project, io_host=io_host, region=target.region)
398
+ toolkit_wrapper = synth_result.toolkit_wrapper
399
+ selection = select_target_stack(synth_result.stack_names, spec.name, target.name)
400
+ if not selection.success:
401
+ end_step("error", str(selection.error))
402
+ return fail(selection.error)
403
+ stack_name = selection.value
404
+ end_step("success")
405
+
406
+ start_step("Check bootstrap status")
407
+ bootstrap_check = preflight.check_bootstrap_needed(context.aws_targets)
408
+ if bootstrap_check.needs_bootstrap:
409
+ if options.auto_confirm:
410
+ logger.log("Bootstrap needed, auto-confirming...")
411
+ preflight.bootstrap_environment(toolkit_wrapper, target)
412
+ elif options.confirm_bootstrap is not None:
413
+ if options.confirm_bootstrap():
414
+ logger.log("Bootstrap needed, confirmed by user...")
415
+ preflight.bootstrap_environment(toolkit_wrapper, target)
416
+ else:
417
+ logger.log("Bootstrap skipped by user", "warn")
418
+ else:
419
+ end_step("error", "Bootstrap required")
420
+ return fail(ValidationError("AWS environment needs bootstrapping. Run with --yes to auto-bootstrap."))
421
+ end_step("success")
422
+
423
+ # Scope to this target's stack so a sibling target's failed stack can't block the deploy.
424
+ start_step("Check stack status")
425
+ deployability = preflight.check_stack_deployability(target.region, [stack_name])
426
+ if not deployability.can_deploy:
427
+ end_step("error", deployability.message)
428
+ return fail(RuntimeError(deployability.message or "Stack is not in a deployable state"))
429
+ end_step("success")
430
+
431
+ if options.plan:
432
+ logger.finalize(True)
433
+ toolkit_wrapper.dispose()
434
+ toolkit_wrapper = None
435
+ return DeployResult(
436
+ success=True,
437
+ target_name=target.name,
438
+ stack_name=stack_name,
439
+ log_path=logger.get_relative_log_path(),
440
+ dependency_sync_result=sync_result,
441
+ )
442
+
443
+ if options.diff:
444
+ start_step("Run CDK diff")
445
+ run_diff(toolkit_wrapper, stack_name, io_host)
446
+ end_step("success")
447
+ logger.finalize(True)
448
+ toolkit_wrapper.dispose()
449
+ toolkit_wrapper = None
450
+ return DeployResult(
451
+ success=True,
452
+ target_name=target.name,
453
+ stack_name=stack_name,
454
+ log_path=logger.get_relative_log_path(),
455
+ dependency_sync_result=sync_result,
456
+ )
457
+
458
+ if not context.is_teardown_deploy and memory_notice.has_managed_memory_harness(config_io, spec.harnesses):
459
+ logger.log(memory_notice.MANAGED_MEMORY_DEPLOY_NOTICE)
460
+ if options.on_notice:
461
+ options.on_notice(memory_notice.MANAGED_MEMORY_DEPLOY_NOTICE)
462
+
463
+ has_gateways = len(gateway_specs) > 0
464
+ start_step("Deploying gateways..." if has_gateways else "Deploy to AWS")
465
+
466
+ if io_host is not None and (options.on_resource_event or options.on_deploy_message):
467
+
468
+ def on_message(msg: DeployMessage) -> None:
469
+ if options.on_resource_event:
470
+ options.on_resource_event(msg.message)
471
+ if options.on_deploy_message:
472
+ options.on_deploy_message(msg)
473
+
474
+ io_host.set_on_message(on_message)
475
+ io_host.set_verbose(True)
476
+
477
+ try:
478
+ run_deploy(toolkit_wrapper, stack_name)
479
+ except Exception as deploy_err:
480
+ if is_changeset_in_progress_error(deploy_err):
481
+ logger.log("Changeset conflict detected - another deployment may be in progress", "warn")
482
+ elif is_stack_in_progress_error(deploy_err):
483
+ logger.log("Stack is busy with another operation - wait for it to finish and retry", "warn")
484
+ raise
485
+
486
+ if io_host is not None:
487
+ io_host.set_verbose(False)
488
+ io_host.set_on_message(None)
489
+ end_step("success")
490
+
491
+ if context.is_teardown_deploy:
492
+ try:
493
+ existing_for_teardown = config_io.read_deployed_state()
494
+ except Exception: # noqa: BLE001
495
+ existing_for_teardown = None
496
+ existing_payments = _resources_json(existing_for_teardown, target.name).get("payments")
497
+ if existing_payments:
498
+ start_step("Clean up payment credentials")
499
+ try:
500
+ pre_deploy_identity.cleanup_payment_credential_providers(
501
+ region=target.region, payments=existing_payments
502
+ )
503
+ end_step("success")
504
+ except Exception as cleanup_err: # noqa: BLE001 - best-effort
505
+ end_step("error", f"Payment cleanup: {get_error_message(cleanup_err)}")
506
+
507
+ start_step("Tear down stack")
508
+ torn = teardown.perform_stack_teardown(target.name, toolkit_wrapper)
509
+ if not torn.success:
510
+ end_step("error", str(torn.error))
511
+ return fail(torn.error)
512
+ end_step("success")
513
+ logger.finalize(True)
514
+ return DeployResult(
515
+ success=True,
516
+ target_name=target.name,
517
+ stack_name=stack_name,
518
+ log_path=logger.get_relative_log_path(),
519
+ dependency_sync_result=sync_result,
520
+ )
521
+
522
+ # ---- Persist deployment state -------------------------------------------------------
523
+ start_step("Persist deployment state")
524
+ outputs = cfn_outputs.get_stack_outputs(target.region, stack_name)
525
+ agent_names = [a.name for a in spec.runtimes or []]
526
+ agents = cfn_outputs.parse_agent_outputs(outputs, agent_names, stack_name)
527
+
528
+ memory_names = [m.name for m in spec.memories or []]
529
+ memories = cfn_outputs.parse_memory_outputs(outputs, memory_names)
530
+ if memory_names and len(memories) != len(memory_names):
531
+ logger.log(f"Deployed-state missing outputs for {len(memory_names) - len(memories)} memory(ies).", "warn")
532
+
533
+ evaluators = cfn_outputs.parse_evaluator_outputs(outputs, [e.name for e in spec.evaluators or []])
534
+ online_eval_configs = cfn_outputs.parse_online_eval_outputs(
535
+ outputs,
536
+ [{"name": c.name, "agent": c.agent, "endpoint": c.endpoint} for c in spec.online_eval_configs or []],
537
+ )
538
+ engine_specs = spec.policy_engines or []
539
+ policy_engines = cfn_outputs.parse_policy_engine_outputs(outputs, [pe.name for pe in engine_specs])
540
+ policies = cfn_outputs.parse_policy_outputs(
541
+ outputs, [{"engineName": pe.name, "policyName": p.name} for pe in engine_specs for p in pe.policies]
542
+ )
543
+ endpoint_specs = [
544
+ {"agentName": r.name, "endpointName": ep} for r in spec.runtimes or [] for ep in (r.endpoints or {})
545
+ ]
546
+ runtime_endpoints = cfn_outputs.parse_runtime_endpoint_outputs(outputs, endpoint_specs)
547
+
548
+ all_gateways = cfn_outputs.parse_gateway_outputs(outputs, {g.name: g for g in gateway_specs})
549
+ http_gateway_names = {g.name for g in gateway_specs if getattr(g, "protocol_type", None) == "None"}
550
+ gateways = {n: s for n, s in all_gateways.items() if n not in http_gateway_names}
551
+ http_gateways = {n: s for n, s in all_gateways.items() if n in http_gateway_names}
552
+
553
+ datasets = cfn_outputs.parse_dataset_outputs(outputs, [d.name for d in spec.datasets or []])
554
+ capacity_providers = cfn_outputs.parse_capacity_provider_outputs(
555
+ outputs, [cp.name for cp in spec.capacity_providers or []]
556
+ )
557
+ config_bundles = cfn_outputs.parse_config_bundle_outputs(outputs, [b.name for b in spec.config_bundles or []])
558
+
559
+ kb_specs = spec.knowledge_bases or []
560
+ kb_names = [kb.name for kb in kb_specs]
561
+ knowledge_bases = cfn_outputs.parse_knowledge_base_outputs(outputs, kb_names)
562
+ if kb_names and len(knowledge_bases) != len(kb_names):
563
+ logger.log(
564
+ f"Deployed-state missing outputs for {len(kb_names) - len(knowledge_bases)} knowledge base(s).", "warn"
565
+ )
566
+ if knowledge_bases:
567
+ try:
568
+ hydrate_knowledge_base_data_sources(
569
+ knowledge_bases=knowledge_bases, knowledge_base_specs=kb_specs, region=target.region
570
+ )
571
+ except Exception as hydrate_err: # noqa: BLE001
572
+ logger.log(f"Failed to hydrate knowledge base data sources: {get_error_message(hydrate_err)}", "warn")
573
+
574
+ payment_specs = []
575
+ for p in spec.payments or []:
576
+ connectors = []
577
+ for c in p.connectors:
578
+ if c.provision_mode == "QUICK_CREATE":
579
+ connectors.append({"name": c.name, "provisionMode": "QUICK_CREATE"})
580
+ else:
581
+ connector: dict[str, Any] = {"name": c.name}
582
+ if c.provision_mode:
583
+ connector["provisionMode"] = c.provision_mode
584
+ connector["credentialProviderArn"] = (deployed_credentials.get(c.credential_name) or {}).get(
585
+ "credentialProviderArn"
586
+ )
587
+ connector["credentialProviderName"] = c.credential_name
588
+ connectors.append(connector)
589
+ payment_specs.append(
590
+ {
591
+ "name": p.name,
592
+ "authorizerType": p.authorizer_type,
593
+ "autoPayment": p.auto_payment,
594
+ "paymentToolAllowlist": p.payment_tool_allowlist,
595
+ "networkPreferences": p.network_preferences,
596
+ "connectors": connectors,
597
+ }
598
+ )
599
+ payments = cfn_outputs.parse_payment_outputs(outputs, payment_specs) if payment_specs else None
600
+
601
+ deployed_harnesses = cfn_outputs.parse_harness_outputs(
602
+ outputs, [h.name for h in spec.harnesses or []], on_warn=lambda m: logger.log(m, "warn")
603
+ )
604
+ end_step("success")
605
+
606
+ deploy_hash: str | None = None
607
+ try:
608
+ deploy_hash = change_detection.compute_project_deploy_hash(config_io)
609
+ except Exception: # noqa: BLE001 - best-effort
610
+ pass
611
+
612
+ try:
613
+ existing_state = config_io.read_deployed_state()
614
+ except Exception: # noqa: BLE001
615
+ existing_state = None
616
+ existing_resources = _resources_json(existing_state, target.name)
617
+ prev_harness_records = existing_resources.get("harnesses")
618
+
619
+ deployed_state = cfn_outputs.build_deployed_state(
620
+ target_name=target.name,
621
+ stack_name=stack_name,
622
+ agents=agents,
623
+ gateways=gateways,
624
+ http_gateways=http_gateways or None,
625
+ existing_state=existing_state,
626
+ identity_kms_key_arn=identity_kms_key_arn,
627
+ credentials=deployed_credentials,
628
+ memories=memories,
629
+ evaluators=evaluators,
630
+ online_eval_configs=online_eval_configs,
631
+ policy_engines=policy_engines,
632
+ policies=policies,
633
+ harnesses=deployed_harnesses,
634
+ runtime_endpoints=runtime_endpoints,
635
+ datasets=datasets,
636
+ config_bundles=config_bundles,
637
+ knowledge_bases=knowledge_bases,
638
+ payments=payments,
639
+ capacity_providers=capacity_providers,
640
+ ab_test_names=[t.name for t in spec.ab_tests or []],
641
+ )
642
+ target_resources = deployed_state["targets"][target.name]["resources"]
643
+ if deploy_hash:
644
+ target_resources["deployHash"] = deploy_hash
645
+
646
+ # CFN succeeded; a failed local write must leave a recovery trail.
647
+ try:
648
+ config_io.write_deployed_state(deployed_state)
649
+ except Exception as write_err:
650
+ logger.log(
651
+ f"WARNING: deploy succeeded but writing agentcore/deployed-state.json failed: {write_err}.\n"
652
+ f" Stack: {stack_name} (region: {target.region})\n"
653
+ " AWS resources are running but the CLI cannot track them locally.\n"
654
+ " Recovery options:\n"
655
+ " 1) Fix the local I/O problem (disk space / permissions on agentcore/) and run "
656
+ "`agentcore status` to refresh.\n"
657
+ " 2) If you want to teardown what was deployed: `aws cloudformation delete-stack "
658
+ f"--stack-name {stack_name} --region {target.region}`"
659
+ )
660
+ raise
661
+
662
+ for drift in compute_harness_version_drift(prev_harness_records, deployed_harnesses):
663
+ logger.log(
664
+ f"Harness {drift.name}: config updated (v{drift.from_} → v{drift.to})"
665
+ if drift.from_ is not None
666
+ else f"Harness {drift.name}: deployed (v{drift.to})"
667
+ )
668
+
669
+ if gateways:
670
+ urls = ", ".join(f"{name}: {gw['gatewayArn']}" for name, gw in gateways.items())
671
+ logger.log(f"Gateway URLs: {urls}")
672
+ for gw in gateways.values():
673
+ for status in gateway_status.get_gateway_target_statuses(gw["gatewayId"], target.region):
674
+ logger.log(f" {status.name}: {gateway_status.format_target_status(status.status)}")
675
+
676
+ end_step("success")
677
+
678
+ post_deploy_warnings: list[str] = []
679
+
680
+ # Auto-payment posture is informational (notes, exit 0), never a partial-failure warning.
681
+ auto_payment_notices = []
682
+ for manager in spec.payments or []:
683
+ if manager.auto_payment is not False:
684
+ limit = manager.default_spend_limit or "10.00"
685
+ auto_payment_notices.append(
686
+ f'Payment manager "{manager.name}": auto-payment is ENABLED — the agent will settle '
687
+ f"402 responses automatically up to the per-session spend limit (${limit}) with no "
688
+ "human approval. Set --auto-payment false on the manager to require manual approval."
689
+ )
690
+
691
+ # Enable only newly deployed online eval configs (don't re-enable ones a user disabled).
692
+ deployed_online_evals = target_resources.get("onlineEvalConfigs") or {}
693
+ previous_online_evals = existing_resources.get("onlineEvalConfigs") or {}
694
+ new_online_evals = [c for c in spec.online_eval_configs or [] if c.name not in previous_online_evals]
695
+ if new_online_evals and deployed_online_evals:
696
+ enable_result = post_deploy_online_evals.enable_online_eval_configs(
697
+ region=target.region,
698
+ online_eval_configs=new_online_evals,
699
+ deployed_online_eval_configs=deployed_online_evals,
700
+ )
701
+ if enable_result.has_errors:
702
+ errors = [r for r in enable_result.results if r.status == "error"]
703
+ logger.log(
704
+ "Online eval enable warnings: " + "; ".join(f'"{e.config_name}": {e.error}' for e in errors), "warn"
705
+ )
706
+ post_deploy_warnings.extend(f'Online eval "{e.config_name}": {e.error}' for e in errors)
707
+
708
+ dataset_specs = spec.datasets or []
709
+ deployed_datasets = target_resources.get("datasets") or {}
710
+ if dataset_specs and deployed_datasets:
711
+ ds_result = post_deploy_datasets.sync_datasets(
712
+ region=target.region,
713
+ datasets=dataset_specs,
714
+ deployed_datasets=deployed_datasets,
715
+ config_base_dir=config_io.get_config_root(),
716
+ )
717
+ if any(r.status == "synced" for r in ds_result.results):
718
+ try:
719
+ updated = to_jsonable(config_io.read_deployed_state())
720
+ except Exception: # noqa: BLE001
721
+ updated = deployed_state
722
+ updated_resources = ((updated.get("targets") or {}).get(target.name) or {}).get("resources")
723
+ if updated_resources is not None:
724
+ updated_resources["datasets"] = ds_result.updated_datasets
725
+ config_io.write_deployed_state(updated)
726
+ deployed_state = updated
727
+ target_resources = updated_resources
728
+ if ds_result.has_errors:
729
+ errors = [r for r in ds_result.results if r.status == "error"]
730
+ logger.log(
731
+ "Dataset sync warnings: " + "; ".join(f'"{e.dataset_name}": {e.error}' for e in errors), "warn"
732
+ )
733
+ post_deploy_warnings.extend(f'Dataset "{e.dataset_name}": {e.error}' for e in errors)
734
+ for r in ds_result.results:
735
+ if r.status == "synced":
736
+ logger.log(
737
+ f'Dataset "{r.dataset_name}": +{r.added} added, ~{r.updated} updated, -{r.deleted} deleted'
738
+ )
739
+
740
+ if kb_specs:
741
+ start_step("Auto-ingest knowledge bases")
742
+ ingest_result = post_deploy_knowledge_bases.auto_ingest_knowledge_bases(
743
+ region=target.region,
744
+ knowledge_bases=kb_specs,
745
+ deployed_knowledge_bases=target_resources.get("knowledgeBases") or {},
746
+ previous_knowledge_bases=existing_resources.get("knowledgeBases"),
747
+ target_name=target.name,
748
+ deployed_state=deployed_state,
749
+ project_root=os.path.abspath(os.path.join(config_io.get_config_root(), "..")),
750
+ on_progress=lambda msg: logger.log(msg),
751
+ )
752
+ kb_records = target_resources.get("knowledgeBases")
753
+ if kb_records:
754
+ for r in ingest_result.results:
755
+ if r.status == "started" and r.new_sources_hash and r.knowledge_base_name in kb_records:
756
+ kb_records[r.knowledge_base_name]["sourcesHash"] = r.new_sources_hash
757
+ config_io.write_deployed_state(deployed_state)
758
+ for r in ingest_result.results:
759
+ if r.status == "started":
760
+ logger.log(
761
+ f'Knowledge base "{r.knowledge_base_name}": ingestion started for '
762
+ f"{r.started_job_count} data source(s)"
763
+ )
764
+ elif r.status == "skipped":
765
+ logger.log(f'Knowledge base "{r.knowledge_base_name}": skipped ({r.reason})')
766
+ else:
767
+ logger.log(f'Knowledge base "{r.knowledge_base_name}": {r.error}', "warn")
768
+ post_deploy_warnings.append(f'Knowledge base "{r.knowledge_base_name}": {r.error}')
769
+ end_step("error" if ingest_result.has_errors else "success")
770
+
771
+ has_invokable = bool(agent_names) or bool(spec.harnesses)
772
+ next_steps = list(AGENT_NEXT_STEPS if has_invokable else MEMORY_ONLY_NEXT_STEPS)
773
+ notes = list(auto_payment_notices)
774
+ quick_create = pca.get_quick_create_connector_authorizations(
775
+ region=target.region, project_spec=spec, payments=payments
776
+ )
777
+ notes.extend(pca.format_quick_create_connector_authorization(q) for q in quick_create)
778
+
779
+ has_python_agent = any(
780
+ (a.entrypoint or "").endswith(".py") or ".py:" in (a.entrypoint or "") for a in spec.runtimes or []
781
+ )
782
+ if (agent_names or has_gateways) and has_python_agent:
783
+ try:
784
+ ts_result = post_deploy_observability.setup_transaction_search(
785
+ region=target.region, account_id=target.account, agent_names=agent_names, has_gateways=has_gateways
786
+ )
787
+ if not ts_result.success:
788
+ logger.log(f"Transaction search setup warning: {ts_result.error}", "warn")
789
+ else:
790
+ notes.append(
791
+ "Transaction search enabled. It takes ~10 minutes for transaction search to be fully "
792
+ "active and for traces from invocations to be indexed."
793
+ )
794
+ except Exception as ts_err: # noqa: BLE001
795
+ logger.log(f"Transaction search setup failed: {get_error_message(ts_err)}", "warn")
796
+
797
+ logger.finalize(True)
798
+ all_warnings = [*orphan_warnings, *post_deploy_warnings]
799
+ return DeployResult(
800
+ success=True,
801
+ target_name=target.name,
802
+ stack_name=stack_name,
803
+ outputs=cfn_outputs.omit_payment_authorization_outputs(outputs),
804
+ log_path=logger.get_relative_log_path(),
805
+ next_steps=next_steps,
806
+ notes=notes,
807
+ post_deploy_warnings=all_warnings or None,
808
+ dependency_sync_result=sync_result,
809
+ )
810
+ except Exception as exc: # noqa: BLE001 - every failure becomes a result, as upstream
811
+ logger.log(get_error_message(exc), "error")
812
+ return fail(to_error(exc))
813
+ finally:
814
+ # Each cleanup step runs regardless of earlier failures.
815
+ if toolkit_wrapper is not None:
816
+ try:
817
+ toolkit_wrapper.dispose()
818
+ except Exception as dispose_err: # noqa: BLE001
819
+ logger.log(f"CDK toolkit dispose failed: {get_error_message(dispose_err)}", "warn")
820
+ if preview_restore is not None:
821
+ try:
822
+ preview_restore()
823
+ except Exception as restore_err: # noqa: BLE001
824
+ logger.log(f"Failed to revert preview vpcId backfill: {get_error_message(restore_err)}", "warn")
825
+ if restore_env is not None:
826
+ restore_env()
827
+
828
+
829
+ __all__ = [
830
+ "AGENT_NEXT_STEPS",
831
+ "MEMORY_ONLY_NEXT_STEPS",
832
+ "HarnessVersionDrift",
833
+ "ValidatedDeployOptions",
834
+ "compute_harness_version_drift",
835
+ "handle_deploy",
836
+ "run_deploy",
837
+ "run_diff",
838
+ "select_target_stack",
839
+ "to_stack_name",
840
+ ]