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,706 @@
1
+ """Harness add/remove (port of src/cli/primitives/HarnessPrimitive.ts).
2
+
3
+ A harness lives in ``app/<name>/harness.json`` (+ ``system-prompt.md``) and is listed in
4
+ ``agentcore.json`` ``harnesses``. Specs are handled in their camelCase JSON form and validated on
5
+ write by ``ConfigIO``. ``register_commands`` also registers the harness ``add/remove tool`` and
6
+ ``add/remove skill`` subcommands.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import json
12
+ import os
13
+ import re
14
+ import shutil
15
+ import sys
16
+ from dataclasses import dataclass, field, fields
17
+ from typing import Any, Literal
18
+
19
+ import typer
20
+
21
+ from agentcore.cli import interactive
22
+ from agentcore.cli.errors import get_error_message
23
+ from agentcore.lib import APP_DIR
24
+ from agentcore.lib.errors.types import BaseError, ResourceNotFoundError, ValidationError, to_error
25
+ from agentcore.lib.result import Err, Ok
26
+ from agentcore.lib.schemas.io.config_io import ConfigIO, to_jsonable
27
+ from agentcore.lib.schemas.io.path_resolver import find_config_root
28
+ from agentcore.operations.harness.orphan import OrphanHarness, find_orphan_harnesses
29
+ from agentcore.operations.harness.skill_utils import validate_git_skill_credential
30
+ from agentcore.primitives.auth_utils import (
31
+ JwtConfigOptions,
32
+ build_authorizer_config_from_jwt_config,
33
+ create_managed_oauth_credential,
34
+ )
35
+ from agentcore.primitives.base import (
36
+ SOURCE_CODE_NOTE,
37
+ BasePrimitive,
38
+ RemovableResource,
39
+ RemovalPreview,
40
+ SchemaChange,
41
+ emit_json,
42
+ )
43
+
44
+ OrphanAction = Literal["keep", "discard"]
45
+
46
+ # Port of tui/screens/harness/types.ts defaults.
47
+ DEFAULT_MODEL_IDS: dict[str, str] = {
48
+ "bedrock": "global.anthropic.claude-sonnet-4-6",
49
+ "open_ai": "gpt-5",
50
+ "gemini": "gemini-2.5-flash",
51
+ "lite_llm": "anthropic/claude-sonnet-4-5",
52
+ }
53
+ DEFAULT_BEDROCK_MANTLE_MODEL_ID = "openai.gpt-oss-120b"
54
+ DEFAULT_SYSTEM_PROMPT = "You are a helpful assistant"
55
+
56
+
57
+ @dataclass
58
+ class AddHarnessOptions:
59
+ """Port of ``AddHarnessOptions`` (snake_case attributes of the upstream camelCase keys)."""
60
+
61
+ name: str
62
+ model_provider: str = "bedrock"
63
+ model_id: str = DEFAULT_MODEL_IDS["bedrock"]
64
+ api_format: str | None = None
65
+ api_key_arn: str | None = None
66
+ api_base: str | None = None
67
+ additional_params: dict[str, Any] | None = None
68
+ temperature: float | None = None
69
+ top_p: float | None = None
70
+ top_k: int | None = None
71
+ model_max_tokens: int | None = None
72
+ system_prompt: str | None = None
73
+ skip_memory: bool | None = None
74
+ memory_mode: str | None = None
75
+ memory_strategies: list[str] | None = None
76
+ memory_event_expiry_days: int | None = None
77
+ memory_encryption_key_arn: str | None = None
78
+ memory_name: str | None = None
79
+ memory_arn: str | None = None
80
+ memory_actor_id: str | None = None
81
+ messages_count: int | None = None
82
+ memory_top_k: int | None = None
83
+ memory_relevance_score: float | None = None
84
+ container_uri: str | None = None
85
+ dockerfile_path: str | None = None
86
+ max_iterations: int | None = None
87
+ max_tokens: int | None = None
88
+ timeout_seconds: float | None = None
89
+ truncation_strategy: str | None = None
90
+ network_mode: str | None = None
91
+ subnets: list[str] | None = None
92
+ security_groups: list[str] | None = None
93
+ vpc_id: str | None = None
94
+ idle_timeout: int | None = None
95
+ max_lifetime: int | None = None
96
+ session_storage_path: str | None = None
97
+ efs_access_points: list[dict[str, str]] | None = None
98
+ s3_access_points: list[dict[str, str]] | None = None
99
+ allowed_tools: list[str] | None = None
100
+ environment_variables: dict[str, str] | None = None
101
+ tags: dict[str, str] | None = None
102
+ with_invoke_script: bool | None = None
103
+ dockerfile_base_dir: str | None = None
104
+ selected_tools: list[str] | None = None
105
+ mcp_name: str | None = None
106
+ mcp_url: str | None = None
107
+ mcp_headers: dict[str, str] | None = None
108
+ gateway_arn: str | None = None
109
+ gateway_outbound_auth: str | None = None
110
+ gateway_provider_arn: str | None = None
111
+ gateway_scopes: list[str] | None = None
112
+ gateway_grant_type: str | None = None
113
+ gateway_custom_parameters: dict[str, str] | None = None
114
+ authorizer_type: str | None = None
115
+ jwt_config: JwtConfigOptions | None = None
116
+ skills: list[dict[str, Any]] | None = field(default=None)
117
+ config_base_dir: str | None = None
118
+
119
+
120
+ _CAMEL = re.compile(r"(?<!^)(?=[A-Z])")
121
+
122
+
123
+ def _snake(key: str) -> str:
124
+ return _CAMEL.sub("_", key).lower()
125
+
126
+
127
+ def _jwt_from_dict(value: Any) -> JwtConfigOptions | None:
128
+ if value is None or isinstance(value, JwtConfigOptions):
129
+ return value
130
+ names = {f.name for f in fields(JwtConfigOptions)}
131
+ return JwtConfigOptions(**{_snake(k): v for k, v in value.items() if _snake(k) in names})
132
+
133
+
134
+ def add_options_from_dict(d: dict[str, Any]) -> AddHarnessOptions:
135
+ """Build options from upstream's camelCase ``AddHarnessOptions`` dict (``None`` = undefined)."""
136
+ names = {f.name for f in fields(AddHarnessOptions)}
137
+ kwargs: dict[str, Any] = {}
138
+ for key, value in d.items():
139
+ attr = _snake(key)
140
+ if attr in names and value is not None:
141
+ kwargs[attr] = value
142
+ if "jwt_config" in kwargs:
143
+ kwargs["jwt_config"] = _jwt_from_dict(kwargs["jwt_config"])
144
+ if "model_id" not in kwargs:
145
+ kwargs["model_id"] = DEFAULT_MODEL_IDS.get(
146
+ kwargs.get("model_provider", "bedrock"), DEFAULT_MODEL_IDS["bedrock"]
147
+ )
148
+ return AddHarnessOptions(**kwargs)
149
+
150
+
151
+ def _num(value: Any) -> Any:
152
+ """JS numbers print integral floats without a fraction (300.0 -> 300)."""
153
+ if isinstance(value, float) and value.is_integer():
154
+ return int(value)
155
+ return value
156
+
157
+
158
+ def parse_container_flag(value: str | None) -> dict[str, str]:
159
+ """Dockerfile path (relative prefix or Dockerfile suffix) vs. container image URI."""
160
+ if not value:
161
+ return {}
162
+ if value.endswith(("Dockerfile", ".dockerfile")) or value.startswith(("./", "../")):
163
+ return {"dockerfilePath": value}
164
+ return {"containerUri": value}
165
+
166
+
167
+ def parse_access_points(raw: list[str] | None) -> list[dict[str, str]] | None:
168
+ """``<accessPointArn>:<mountPath>`` entries, split on the LAST colon (the ARN contains colons)."""
169
+ if not raw:
170
+ return None
171
+ result = []
172
+ for entry in raw:
173
+ sep = entry.rfind(":")
174
+ if sep <= 0 or sep == len(entry) - 1:
175
+ raise Exception(f'Invalid access point "{entry}" (expected <accessPointArn>:<mountPath>)')
176
+ result.append({"accessPointArn": entry[:sep], "mountPath": entry[sep + 1 :]})
177
+ return result
178
+
179
+
180
+ def js_error_object(err: BaseException) -> dict[str, Any]:
181
+ """``JSON.parse(JSON.stringify(err))``: typed errors carry own ``name``/``errorSource``; plain Errors are ``{}``."""
182
+ if isinstance(err, BaseError):
183
+ return {"name": err.name, "errorSource": err.error_source}
184
+ return {}
185
+
186
+
187
+ class HarnessPrimitive(BasePrimitive):
188
+ kind = "harness"
189
+ label = "Harness"
190
+
191
+ add_options_from_dict = staticmethod(add_options_from_dict)
192
+ parse_container_flag = staticmethod(parse_container_flag)
193
+
194
+ # --- add ----------------------------------------------------------------------------
195
+
196
+ def add(self, options: AddHarnessOptions | dict[str, Any]) -> Ok[dict[str, Any]] | Err[Exception]:
197
+ if isinstance(options, dict):
198
+ options = add_options_from_dict(options)
199
+ try:
200
+ config_base_dir = options.config_base_dir or find_config_root()
201
+ if not config_base_dir:
202
+ return Err(ResourceNotFoundError("No agentcore project found. Run `agentcore create` first."))
203
+ config_io = ConfigIO(base_dir=config_base_dir)
204
+ project = to_jsonable(self.read_project_spec(config_io))
205
+ harnesses = list(project.get("harnesses") or [])
206
+ if any(h["name"] == options.name for h in harnesses):
207
+ raise ValueError(f'{self.label} "{options.name}" already exists.')
208
+
209
+ memory_ref = self._build_memory_ref(options)
210
+
211
+ dockerfile: str | None = None
212
+ if options.dockerfile_path:
213
+ project_root = os.path.dirname(config_base_dir)
214
+ base = options.dockerfile_base_dir or project_root
215
+ src = (
216
+ options.dockerfile_path
217
+ if os.path.isabs(options.dockerfile_path)
218
+ else os.path.abspath(os.path.join(base, options.dockerfile_path))
219
+ )
220
+ if not os.path.exists(src):
221
+ return Err(ResourceNotFoundError(f"Dockerfile not found at: {src}"))
222
+ app_dir = os.path.join(project_root, APP_DIR, options.name)
223
+ os.makedirs(app_dir, exist_ok=True)
224
+ dockerfile = os.path.basename(src)
225
+ shutil.copyfile(src, os.path.join(app_dir, dockerfile))
226
+
227
+ tools = self._build_tools(options)
228
+
229
+ skills: list[dict[str, Any]] = []
230
+ for s in options.skills or []:
231
+ if s.get("s3Uri"):
232
+ skills.append({"s3Uri": s["s3Uri"]})
233
+ elif s.get("gitUrl"):
234
+ if s.get("credentialName"):
235
+ validation = validate_git_skill_credential(project, s["credentialName"])
236
+ if not validation.success:
237
+ return validation
238
+ entry: dict[str, Any] = {"gitUrl": s["gitUrl"]}
239
+ if s.get("gitPath"):
240
+ entry["path"] = s["gitPath"]
241
+ if s.get("credentialName"):
242
+ auth = {"credentialName": s["credentialName"]}
243
+ if s.get("username"):
244
+ auth["username"] = s["username"]
245
+ entry["auth"] = auth
246
+ skills.append(entry)
247
+ elif s.get("awsSkills") is not None:
248
+ skills.append({"awsSkills": {"paths": s["awsSkills"]} if s["awsSkills"] else {}})
249
+ else:
250
+ skills.append({"path": s.get("path")})
251
+
252
+ model: dict[str, Any] = {"provider": options.model_provider, "modelId": options.model_id}
253
+ if options.api_format:
254
+ model["apiFormat"] = options.api_format
255
+ if options.api_key_arn:
256
+ model["apiKeyArn"] = options.api_key_arn
257
+ if options.api_base:
258
+ model["apiBase"] = options.api_base
259
+ if options.additional_params:
260
+ model["additionalParams"] = options.additional_params
261
+ for key, value in (
262
+ ("temperature", options.temperature),
263
+ ("topP", options.top_p),
264
+ ("topK", options.top_k),
265
+ ("maxTokens", options.model_max_tokens),
266
+ ):
267
+ if value is not None:
268
+ model[key] = _num(value)
269
+
270
+ spec: dict[str, Any] = {"name": options.name, "model": model, "tools": tools, "skills": skills}
271
+ if options.system_prompt:
272
+ spec["systemPrompt"] = options.system_prompt
273
+ if options.allowed_tools:
274
+ spec["allowedTools"] = options.allowed_tools
275
+ if memory_ref:
276
+ spec["memory"] = memory_ref
277
+ if options.container_uri:
278
+ spec["containerUri"] = options.container_uri
279
+ if dockerfile:
280
+ spec["dockerfile"] = dockerfile
281
+ for key, value in (
282
+ ("maxIterations", options.max_iterations),
283
+ ("maxTokens", options.max_tokens),
284
+ ("timeoutSeconds", options.timeout_seconds),
285
+ ):
286
+ if value is not None:
287
+ spec[key] = _num(value)
288
+ if options.truncation_strategy:
289
+ spec["truncation"] = {"strategy": options.truncation_strategy}
290
+ if options.network_mode:
291
+ spec["networkMode"] = options.network_mode
292
+ if options.network_mode == "VPC" and options.subnets and options.security_groups:
293
+ network: dict[str, Any] = {"subnets": options.subnets, "securityGroups": options.security_groups}
294
+ if options.vpc_id:
295
+ network["vpcId"] = options.vpc_id
296
+ spec["networkConfig"] = network
297
+ lifecycle = self._build_lifecycle_config(options)
298
+ if lifecycle:
299
+ spec["lifecycleConfig"] = lifecycle
300
+ if options.session_storage_path:
301
+ spec["sessionStoragePath"] = options.session_storage_path
302
+ if options.efs_access_points:
303
+ spec["efsAccessPoints"] = options.efs_access_points
304
+ if options.s3_access_points:
305
+ spec["s3AccessPoints"] = options.s3_access_points
306
+ if options.environment_variables:
307
+ spec["environmentVariables"] = options.environment_variables
308
+ if options.tags:
309
+ spec["tags"] = options.tags
310
+ if options.authorizer_type:
311
+ spec["authorizerType"] = options.authorizer_type
312
+ if options.authorizer_type == "CUSTOM_JWT" and options.jwt_config:
313
+ spec["authorizerConfiguration"] = build_authorizer_config_from_jwt_config(options.jwt_config)
314
+
315
+ config_io.write_harness_spec(options.name, spec)
316
+
317
+ harness_dir = config_io.get_path_resolver().get_harness_dir(options.name)
318
+ prompt = options.system_prompt if (options.system_prompt or "").strip() else DEFAULT_SYSTEM_PROMPT
319
+ with open(os.path.join(harness_dir, "system-prompt.md"), "w", encoding="utf-8") as fh:
320
+ fh.write(prompt)
321
+
322
+ if options.with_invoke_script:
323
+ from agentcore.templates.template_root import get_template_path
324
+
325
+ template = get_template_path("harness", "invoke.py.template").read_text(encoding="utf-8")
326
+ template = template.replace("{{HARNESS_ARN}}", "<your-harness-arn>", 1)
327
+ template = template.replace("{{REGION}}", "<your-region>", 1)
328
+ with open(os.path.join(harness_dir, "invoke.py"), "w", encoding="utf-8") as fh:
329
+ fh.write(template)
330
+
331
+ project["harnesses"] = [*harnesses, {"name": options.name, "path": f"app/{options.name}"}]
332
+ self.write_project_spec(project, config_io)
333
+
334
+ if options.jwt_config and options.jwt_config.client_id and options.jwt_config.client_secret:
335
+ create_managed_oauth_credential(
336
+ options.name,
337
+ options.jwt_config,
338
+ lambda spec_: self.write_project_spec(spec_, config_io),
339
+ lambda: self.read_project_spec(config_io),
340
+ config_base_dir,
341
+ )
342
+
343
+ return Ok({"harnessName": options.name, "memoryMode": memory_ref["mode"] if memory_ref else None})
344
+ except Exception as exc: # noqa: BLE001
345
+ return Err(to_error(exc))
346
+
347
+ @staticmethod
348
+ def _build_tools(options: AddHarnessOptions) -> list[dict[str, Any]]:
349
+ tools: list[dict[str, Any]] = []
350
+ for tool_type in options.selected_tools or []:
351
+ if tool_type == "agentcore_browser":
352
+ tools.append({"type": "agentcore_browser", "name": "browser"})
353
+ elif tool_type == "agentcore_code_interpreter":
354
+ tools.append({"type": "agentcore_code_interpreter", "name": "code-interpreter"})
355
+ elif tool_type == "remote_mcp" and options.mcp_name and options.mcp_url:
356
+ remote: dict[str, Any] = {"url": options.mcp_url}
357
+ if options.mcp_headers:
358
+ remote["headers"] = options.mcp_headers
359
+ tools.append({"type": "remote_mcp", "name": options.mcp_name, "config": {"remoteMcp": remote}})
360
+ elif tool_type == "agentcore_gateway" and options.gateway_arn:
361
+ outbound: dict[str, Any] | None = None
362
+ if options.gateway_outbound_auth == "awsIam":
363
+ outbound = {"awsIam": {}}
364
+ elif options.gateway_outbound_auth == "none":
365
+ outbound = {"none": {}}
366
+ elif (
367
+ options.gateway_outbound_auth == "oauth" and options.gateway_provider_arn and options.gateway_scopes
368
+ ):
369
+ oauth: dict[str, Any] = {
370
+ "providerArn": options.gateway_provider_arn,
371
+ "scopes": options.gateway_scopes,
372
+ }
373
+ if options.gateway_grant_type:
374
+ oauth["grantType"] = options.gateway_grant_type
375
+ if options.gateway_custom_parameters:
376
+ oauth["customParameters"] = options.gateway_custom_parameters
377
+ outbound = {"oauth": oauth}
378
+ gateway: dict[str, Any] = {"gatewayArn": options.gateway_arn}
379
+ if outbound:
380
+ gateway["outboundAuth"] = outbound
381
+ tools.append({"type": "agentcore_gateway", "name": "gateway", "config": {"agentCoreGateway": gateway}})
382
+ return tools
383
+
384
+ @staticmethod
385
+ def _build_lifecycle_config(options: AddHarnessOptions) -> dict[str, Any] | None:
386
+ if options.idle_timeout is None and options.max_lifetime is None:
387
+ return None
388
+ config: dict[str, Any] = {}
389
+ if options.idle_timeout is not None:
390
+ config["idleRuntimeSessionTimeout"] = _num(options.idle_timeout)
391
+ if options.max_lifetime is not None:
392
+ config["maxLifetime"] = _num(options.max_lifetime)
393
+ return config
394
+
395
+ @staticmethod
396
+ def _build_memory_ref(options: AddHarnessOptions) -> dict[str, Any]:
397
+ """existing (a reference or --memory-mode existing) > managed (explicit) > disabled (default)."""
398
+ if options.memory_arn or options.memory_name or options.memory_mode == "existing":
399
+ ref: dict[str, Any] = {"mode": "existing"}
400
+ if options.memory_name:
401
+ ref["name"] = options.memory_name
402
+ if options.memory_arn:
403
+ ref["arn"] = options.memory_arn
404
+ if options.memory_actor_id:
405
+ ref["actorId"] = options.memory_actor_id
406
+ if options.messages_count is not None:
407
+ ref["messagesCount"] = _num(options.messages_count)
408
+ if options.memory_top_k is not None or options.memory_relevance_score is not None:
409
+ tuning: dict[str, Any] = {}
410
+ if options.memory_top_k is not None:
411
+ tuning["topK"] = _num(options.memory_top_k)
412
+ if options.memory_relevance_score is not None:
413
+ tuning["relevanceScore"] = _num(options.memory_relevance_score)
414
+ ref["retrievalConfig"] = tuning
415
+ return ref
416
+ managed_requested = (
417
+ options.memory_mode == "managed"
418
+ or len(options.memory_strategies or []) > 0
419
+ or options.memory_event_expiry_days is not None
420
+ or options.memory_encryption_key_arn is not None
421
+ )
422
+ if managed_requested:
423
+ ref = {"mode": "managed"}
424
+ if options.memory_strategies:
425
+ ref["strategies"] = options.memory_strategies
426
+ if options.memory_event_expiry_days is not None:
427
+ ref["eventExpiryDuration"] = _num(options.memory_event_expiry_days)
428
+ if options.memory_encryption_key_arn:
429
+ ref["encryptionKeyArn"] = options.memory_encryption_key_arn
430
+ return ref
431
+ return {"mode": "disabled"}
432
+
433
+ # --- remove -------------------------------------------------------------------------
434
+
435
+ def remove(self, name: str, orphan_action: OrphanAction | None = None) -> Ok[None] | Err[Exception]:
436
+ try:
437
+ config_root = find_config_root()
438
+ if not config_root:
439
+ return Err(ResourceNotFoundError("No agentcore project found."))
440
+ config_io = ConfigIO(base_dir=config_root)
441
+ project = to_jsonable(self.read_project_spec(config_io))
442
+ deployed_state = self._read_state(config_io)
443
+
444
+ orphans = find_orphan_harnesses(deployed_state, name)
445
+ if orphans:
446
+ return self._remove_orphan(name, orphans, orphan_action, config_io, project)
447
+
448
+ if not any(h["name"] == name for h in project.get("harnesses") or []):
449
+ return Err(ResourceNotFoundError(f'Harness "{name}" not found.'))
450
+
451
+ if orphan_action:
452
+ return Err(
453
+ ValidationError(
454
+ f'--keep/--discard only apply to a preview-build (orphan) harness. "{name}" is managed by '
455
+ "CloudFormation; remove it without those flags and run `agentcore deploy` to delete it from AWS."
456
+ )
457
+ )
458
+
459
+ self._remove_from_spec(name, config_io, project)
460
+ return Ok(None)
461
+ except Exception as exc: # noqa: BLE001
462
+ return Err(to_error(exc))
463
+
464
+ @staticmethod
465
+ def _read_state(config_io: ConfigIO) -> dict[str, Any] | None:
466
+ try:
467
+ return to_jsonable(config_io.read_deployed_state())
468
+ except Exception: # noqa: BLE001 - `.catch(() => undefined)`
469
+ return None
470
+
471
+ def _remove_orphan(
472
+ self,
473
+ name: str,
474
+ orphans: list[OrphanHarness],
475
+ action: OrphanAction | None,
476
+ config_io: ConfigIO,
477
+ project: dict[str, Any],
478
+ ) -> Ok[None] | Err[Exception]:
479
+ if not action:
480
+ return Err(
481
+ ValidationError(
482
+ f'No changes were made — "{name}" was not deleted. It was created by the preview build and is '
483
+ "not managed by CloudFormation, so CloudFormation cannot delete it. Removing it deletes the "
484
+ "resource directly from your AWS account. Re-run with an explicit choice:\n"
485
+ " --keep delete it from AWS but keep it in agentcore.json (it moves to GA; the next "
486
+ "`agentcore deploy` recreates it under CloudFormation)\n"
487
+ " --discard delete it from AWS and remove it from agentcore.json (you no longer want it)"
488
+ )
489
+ )
490
+
491
+ from agentcore.aws.agentcore_harness import delete_harness, is_harness_not_found_error
492
+
493
+ for orphan in orphans:
494
+ try:
495
+ delete_harness(region=orphan.region, harness_id=orphan.harness_id)
496
+ except Exception as exc: # noqa: BLE001
497
+ if not is_harness_not_found_error(exc):
498
+ return Err(
499
+ Exception(
500
+ f'Failed to delete orphan harness "{name}" ({orphan.harness_id}) in {orphan.region}: '
501
+ f"{get_error_message(exc)}. Local state was left unchanged — resolve the error and retry."
502
+ )
503
+ )
504
+
505
+ state = self._read_state(config_io)
506
+ if state:
507
+ for orphan in orphans:
508
+ harnesses = (((state.get("targets") or {}).get(orphan.target_name) or {}).get("resources") or {}).get(
509
+ "harnesses"
510
+ )
511
+ if harnesses is not None:
512
+ harnesses.pop(orphan.name, None)
513
+ config_io.write_deployed_state(state)
514
+
515
+ if action == "discard" and any(h["name"] == name for h in project.get("harnesses") or []):
516
+ self._remove_from_spec(name, config_io, project)
517
+ return Ok(None)
518
+
519
+ def _remove_from_spec(self, name: str, config_io: ConfigIO, project: dict[str, Any]) -> None:
520
+ project["harnesses"] = [h for h in project.get("harnesses") or [] if h["name"] != name]
521
+ memory_name = f"{name}Memory"
522
+ if any(m["name"] == memory_name for m in project.get("memories") or []):
523
+ project["memories"] = [m for m in project.get("memories") or [] if m["name"] != memory_name]
524
+ self.write_project_spec(project, config_io)
525
+ shutil.rmtree(config_io.get_path_resolver().get_harness_dir(name), ignore_errors=True)
526
+
527
+ def preview_remove(self, name: str) -> RemovalPreview:
528
+ project = to_jsonable(self.read_project_spec())
529
+ harnesses = project.get("harnesses") or []
530
+ if not any(h["name"] == name for h in harnesses):
531
+ raise Exception(f'Harness "{name}" not found.')
532
+ memory_name = f"{name}Memory"
533
+ has_memory = any(m["name"] == memory_name for m in project.get("memories") or [])
534
+ summary = [f"Removing harness: {name}"]
535
+ if has_memory:
536
+ summary.append(f"Removing associated memory: {memory_name}")
537
+ after = {**project, "harnesses": [h for h in harnesses if h["name"] != name]}
538
+ if has_memory:
539
+ after["memories"] = [m for m in project.get("memories") or [] if m["name"] != memory_name]
540
+ return RemovalPreview(summary, [f"app/{name}"], [SchemaChange("agentcore/agentcore.json", project, after)])
541
+
542
+ def get_removable(self) -> list[RemovableResource]:
543
+ try:
544
+ return [RemovableResource(h["name"]) for h in to_jsonable(self.read_project_spec()).get("harnesses") or []]
545
+ except Exception: # noqa: BLE001
546
+ return []
547
+
548
+ def is_orphan(self, name: str) -> bool:
549
+ try:
550
+ config_root = find_config_root()
551
+ if not config_root:
552
+ return False
553
+ return len(find_orphan_harnesses(self._read_state(ConfigIO(base_dir=config_root)), name)) > 0
554
+ except Exception: # noqa: BLE001
555
+ return False
556
+
557
+ # --- CLI ----------------------------------------------------------------------------
558
+
559
+ def register_commands(self, add_app: typer.Typer, remove_app: typer.Typer) -> None:
560
+ from agentcore.cli.commands.add.skill_command import register_add_skill
561
+ from agentcore.cli.commands.add.tool_command import register_add_tool
562
+ from agentcore.cli.commands.remove.skill_command import register_remove_skill
563
+ from agentcore.cli.commands.remove.tool_command import register_remove_tool
564
+ from agentcore.primitives._harness_cli import register_add_harness
565
+
566
+ register_add_harness(self, add_app)
567
+ self._register_harness_remove_subcommand(remove_app)
568
+ register_add_tool(add_app)
569
+ register_add_skill(add_app)
570
+ register_remove_tool(remove_app)
571
+ register_remove_skill(remove_app)
572
+
573
+ def _register_harness_remove_subcommand(self, remove_app: typer.Typer) -> None:
574
+ @remove_app.command(self.kind, help=f"Remove {self.article} {self.label.lower()} from the project")
575
+ def remove_command(
576
+ name: str | None = typer.Option(None, "--name", help="Name of resource to remove [non-interactive]"),
577
+ yes: bool = typer.Option(False, "-y", "--yes", help="Skip confirmation prompt [non-interactive]"),
578
+ as_json: bool = typer.Option(False, "--json", help="Output as JSON [non-interactive]"),
579
+ keep: bool = typer.Option(
580
+ False,
581
+ "--keep",
582
+ help="For a preview-build orphan: delete it from AWS but keep it in agentcore.json (it moves to GA; "
583
+ "the next deploy recreates it under CloudFormation)",
584
+ ),
585
+ discard: bool = typer.Option(
586
+ False,
587
+ "--discard",
588
+ help="For a preview-build orphan: delete it from AWS and remove it from agentcore.json",
589
+ ),
590
+ ) -> None:
591
+ self._run_harness_remove(name, yes, as_json, keep, discard)
592
+
593
+ def _run_harness_remove(self, name: str | None, yes: bool, as_json: bool, keep: bool, discard: bool) -> None:
594
+ try:
595
+ if not find_config_root():
596
+ typer.echo("No agentcore project found. Run `agentcore create` first.", err=True)
597
+ raise typer.Exit(1)
598
+ if keep and discard:
599
+ emit_json({"success": False, "error": "--keep and --discard are mutually exclusive"})
600
+ raise typer.Exit(1)
601
+ action: OrphanAction | None = "keep" if keep else "discard" if discard else None
602
+
603
+ if name or yes or as_json or action:
604
+ if not name:
605
+ emit_json({"success": False, "error": "--name is required"})
606
+ raise typer.Exit(1)
607
+ result = self.remove(name, action)
608
+ if not result.success and not action and not as_json and self.is_orphan(name):
609
+ typer.echo(f"Error: {get_error_message(result.error)}", err=True)
610
+ raise typer.Exit(1)
611
+ emit_json(
612
+ {
613
+ "success": result.success,
614
+ "resourceType": self.kind,
615
+ "resourceName": name,
616
+ "message": f"Removed {self.label.lower()} '{name}'" if result.success else None,
617
+ "note": SOURCE_CODE_NOTE if result.success else None,
618
+ "error": None if result.success else get_error_message(result.error),
619
+ }
620
+ )
621
+ raise typer.Exit(0 if result.success else 1)
622
+
623
+ interactive.require_tty()
624
+ self.remove_interactive()
625
+ except typer.Exit:
626
+ raise
627
+ except Exception as exc: # noqa: BLE001
628
+ if as_json:
629
+ emit_json({"success": False, "error": get_error_message(exc)})
630
+ else:
631
+ typer.echo(f"Error: {get_error_message(exc)}", err=True)
632
+ raise typer.Exit(1) from None
633
+
634
+ def remove_interactive(self) -> None:
635
+ """RemoveFlow for harnesses: orphans get the delete-and-keep / delete-and-discard choice."""
636
+ removable = self.get_removable()
637
+ if not removable:
638
+ typer.echo(f"No {self.label.lower()} resources to remove.")
639
+ return
640
+ name = interactive.select(
641
+ f"Select {self.article} {self.label.lower()} to remove",
642
+ [interactive.Choice(r.name, r.name) for r in removable],
643
+ )
644
+ action: OrphanAction | None = None
645
+ if self.is_orphan(name):
646
+ choice = interactive.select(
647
+ f'"{name}" was created by the preview build and is not managed by CloudFormation. '
648
+ "Removing it deletes it directly from your AWS account.",
649
+ [
650
+ interactive.Choice(
651
+ "Delete from AWS and keep in agentcore.json",
652
+ "keep",
653
+ "It moves to GA; the next `agentcore deploy` recreates it under CloudFormation",
654
+ ),
655
+ interactive.Choice(
656
+ "Delete from AWS and remove from agentcore.json", "discard", "You no longer want it"
657
+ ),
658
+ interactive.Choice("Cancel", "cancel"),
659
+ ],
660
+ )
661
+ if choice == "cancel":
662
+ typer.echo("Cancelled.")
663
+ return
664
+ action = choice
665
+ else:
666
+ preview = self.preview_remove(name)
667
+ for line in preview.summary:
668
+ typer.echo(f" {line}")
669
+ for directory in preview.directories_to_delete:
670
+ typer.echo(f" Delete directory: {directory}")
671
+ if not interactive.confirm(f"Remove {self.label.lower()} '{name}'?", default=False):
672
+ typer.echo("Cancelled.")
673
+ return
674
+ result = self.remove(name, action)
675
+ if not result.success:
676
+ typer.echo(f"Error: {get_error_message(result.error)}", err=True)
677
+ raise typer.Exit(1)
678
+ typer.echo(f"Removed {self.label.lower()} '{name}'")
679
+ typer.echo(SOURCE_CODE_NOTE)
680
+
681
+ def add_interactive(self) -> None:
682
+ from agentcore.primitives._harness_wizard import run_add_harness_wizard
683
+
684
+ run_add_harness_wizard(self)
685
+
686
+
687
+ def emit_harness_add_failure(result: Err[Exception], as_json: bool) -> None:
688
+ """``console.log(JSON.stringify(result))`` / ``console.error(result.error)`` for a failed add."""
689
+ if as_json:
690
+ typer.echo(json.dumps({"success": False, "error": js_error_object(result.error)}, separators=(",", ":")))
691
+ else:
692
+ name = result.error.name if isinstance(result.error, BaseError) else "Error"
693
+ sys.stderr.write(f"{name}: {get_error_message(result.error)}\n")
694
+
695
+
696
+ __all__ = [
697
+ "DEFAULT_BEDROCK_MANTLE_MODEL_ID",
698
+ "DEFAULT_MODEL_IDS",
699
+ "AddHarnessOptions",
700
+ "HarnessPrimitive",
701
+ "add_options_from_dict",
702
+ "parse_access_points",
703
+ "parse_container_flag",
704
+ ]
705
+
706
+ PRIMITIVE = HarnessPrimitive()