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,726 @@
1
+ """Interactive add-harness wizard: prompt-based port of tui/screens/harness (AddHarnessScreen,
2
+ useAddHarnessWizard, AddHarnessFlow).
3
+
4
+ Step order (upstream ``allSteps``): name -> model provider -> API format (bedrock/open_ai) -> API key
5
+ ARN (non-bedrock) -> API base + additional params (lite_llm) -> custom environment (+ URI/Dockerfile)
6
+ -> memory mode (+ existing reference) -> advanced settings -> tools -> skills -> auth -> network ->
7
+ memory tuning -> allowed tools -> lifecycle -> execution & sampling -> truncation -> filesystem
8
+ storage -> confirm.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import json
14
+ import re
15
+ from typing import TYPE_CHECKING, Any
16
+
17
+ import typer
18
+
19
+ from agentcore.cli import interactive
20
+ from agentcore.cli.commands.add._common import first_issue
21
+ from agentcore.cli.commands.shared.arn_utils import ARN_VALIDATION_MESSAGE, is_valid_arn
22
+ from agentcore.cli.errors import get_error_message
23
+ from agentcore.cli.naming import generate_unique_name
24
+ from agentcore.lib.schemas.io.config_io import ConfigIO, to_jsonable
25
+ from agentcore.operations.deploy.managed_memory_notice import MANAGED_MEMORY_ADD_NOTICE
26
+ from agentcore.primitives.credential_utils import compute_managed_oauth_credential_name
27
+
28
+ if TYPE_CHECKING:
29
+ from agentcore.primitives.harness import HarnessPrimitive
30
+
31
+ C = interactive.Choice
32
+
33
+ MODEL_PROVIDER_OPTIONS = (
34
+ ("bedrock", "Amazon Bedrock", "Default: global.anthropic.claude-sonnet-4-6"),
35
+ ("open_ai", "OpenAI", "Default: gpt-5 (requires API key ARN)"),
36
+ ("gemini", "Google Gemini", "Default: gemini-2.5-flash (requires API key ARN)"),
37
+ ("lite_llm", "LiteLLM", "Default: anthropic/claude-sonnet-4-5 (API key ARN optional)"),
38
+ )
39
+ BEDROCK_API_FORMAT_OPTIONS = (
40
+ ("converse_stream", "Converse Stream", "Standard Bedrock Converse API (default)"),
41
+ ("responses", "Responses", "OpenAI Responses API via Bedrock Mantle"),
42
+ ("chat_completions", "Chat Completions", "OpenAI Chat Completions API via Bedrock Mantle"),
43
+ )
44
+ OPENAI_API_FORMAT_OPTIONS = (
45
+ ("responses", "Responses", "OpenAI Responses API (default)"),
46
+ ("chat_completions", "Chat Completions", "OpenAI Chat Completions API"),
47
+ )
48
+ TRUNCATION_STRATEGY_OPTIONS = (
49
+ ("sliding_window", "Sliding window", "Keep most recent messages"),
50
+ ("summarization", "Summarization", "Compress older context"),
51
+ ("none", "None", "Disable truncation"),
52
+ )
53
+ ADVANCED_SETTING_OPTIONS = (
54
+ ("tools", "Tools", "Add browser, code interpreter, MCP, or gateway tools"),
55
+ ("skills", "Skills", "Add agent skills"),
56
+ ("memory-managed-tuning", "Memory tuning", "Managed memory: strategies, event retention, encryption key"),
57
+ (
58
+ "memory-existing-tuning",
59
+ "Memory tuning",
60
+ "Existing memory: actor ID, messages count, retrieval (topK, relevance)",
61
+ ),
62
+ ("allowed-tools", "Allowed tools", "Restrict which tools the agent may invoke"),
63
+ ("auth", "Authentication", "Inbound auth: AWS_IAM or Custom JWT"),
64
+ ("network", "Network", "Deploy inside a VPC with custom subnets and security groups"),
65
+ ("lifecycle", "Lifecycle", "Set idle timeout and max session lifetime"),
66
+ ("execution", "Execution & sampling", "Cap iterations, tokens, timeout; tune temperature, topP, topK"),
67
+ ("truncation", "Truncation", "Choose how context is managed when it exceeds limits"),
68
+ (
69
+ "session-storage",
70
+ "Filesystem Storage",
71
+ "Mount session storage, EFS, or S3 Files persistent storage (requires VPC)",
72
+ ),
73
+ )
74
+ MEMORY_MODE_OPTIONS = (
75
+ ("disabled", "No memory", "Default"),
76
+ ("managed", "Managed", "AgentCore creates and manages memory for this harness"),
77
+ ("existing", "Existing", "Reference an existing memory by name or ARN"),
78
+ )
79
+ MANAGED_STRATEGY_OPTIONS = (
80
+ ("SEMANTIC", "Semantic", "Extract and retrieve semantic facts"),
81
+ ("SUMMARIZATION", "Summarization", "Summarize conversation history"),
82
+ ("USER_PREFERENCE", "User preference", "Track user preferences"),
83
+ ("EPISODIC", "Episodic", "Recall past episodes/sessions"),
84
+ )
85
+ CONTAINER_MODE_OPTIONS = (
86
+ ("none", "Default Environment", "Includes Python, Bash, File tools"),
87
+ ("uri", "Container URI", "Use a pre-built container image (ECR URI)"),
88
+ ("dockerfile", "Dockerfile", "Bring your own Dockerfile"),
89
+ )
90
+ TOOL_SELECT_OPTIONS = (
91
+ ("agentcore_browser", "AgentCore Browser", "Web browsing and automation"),
92
+ ("agentcore_code_interpreter", "AgentCore Code Interpreter", "Sandboxed code execution"),
93
+ ("agentcore_gateway", "AgentCore Gateway", "Connect via gateway"),
94
+ ("remote_mcp", "Remote MCP Server", "Connect to an MCP server"),
95
+ )
96
+ NETWORK_MODE_OPTIONS = (("PUBLIC", "Public", "Internet-facing"), ("VPC", "VPC", "Deploy within a VPC"))
97
+ AUTHORIZER_TYPE_OPTIONS = (
98
+ ("AWS_IAM", "AWS IAM", "Use AWS IAM authentication (default)"),
99
+ ("CUSTOM_JWT", "Custom JWT", "Use a custom JWT authorizer (OIDC)"),
100
+ )
101
+ GATEWAY_OUTBOUND_AUTH_OPTIONS = (
102
+ ("awsIam", "AWS IAM (default)", "SigV4 signing with the harness execution role"),
103
+ ("none", "None", "No authentication headers"),
104
+ ("oauth", "OAuth", "Bearer token via AgentCore Identity credential provider"),
105
+ )
106
+ SKILL_SOURCE_TYPE_OPTIONS = (
107
+ ("path", "Path", "Path to an installed skill in the environment"),
108
+ ("s3", "S3", "S3 URI (s3://bucket/path)"),
109
+ ("git", "Git", "HTTPS git repository URL"),
110
+ ("aws_skills", "AWS Skills", "Built-in AWS skills (github.com/aws/agent-toolkit-for-aws/tree/main/skills)"),
111
+ )
112
+
113
+ SUBNET_ID_PATTERN = re.compile(r"^subnet-[0-9a-zA-Z]{8,17}$")
114
+ SECURITY_GROUP_ID_PATTERN = re.compile(r"^sg-[0-9a-zA-Z]{8,17}$")
115
+ _ALLOWED_TOOL = re.compile(r"^(\*|@?[^/]+(/[^/]+)?)$")
116
+
117
+
118
+ def _choices(options: tuple[tuple[str, str, str], ...]) -> list[interactive.Choice]:
119
+ return [C(title, value, description) for value, title, description in options]
120
+
121
+
122
+ def _title(options: tuple[tuple[str, str, str], ...], value: str) -> str:
123
+ return next((t for v, t, _ in options if v == value), value)
124
+
125
+
126
+ def _js_int(value: str) -> int | None:
127
+ """``parseInt(value, 10)``; None for NaN."""
128
+ match = re.match(r"^\s*([+-]?\d+)", value)
129
+ return int(match.group(1)) if match else None
130
+
131
+
132
+ def _js_float(value: str) -> float | None:
133
+ """``parseFloat(value)``; None for NaN."""
134
+ match = re.match(r"^\s*([+-]?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?)", value)
135
+ return float(match.group(1)) if match else None
136
+
137
+
138
+ def _num(value: float | None) -> float | int | None:
139
+ return int(value) if isinstance(value, float) and value.is_integer() else value
140
+
141
+
142
+ def _csv(value: str) -> list[str]:
143
+ return [s.strip() for s in value.split(",") if s.strip()]
144
+
145
+
146
+ def _validate_id_list(value: str, pattern: re.Pattern[str], label: str, example: str) -> str | None:
147
+ ids = _csv(value)
148
+ if not ids:
149
+ return f"At least one {label} is required for VPC mode"
150
+ bad = next((i for i in ids if not pattern.match(i)), None)
151
+ return f'Invalid {label} "{bad}" (expected e.g. {example})' if bad else None
152
+
153
+
154
+ def _err(check: Any) -> str | None:
155
+ return None if check is True else check
156
+
157
+
158
+ def _int_range(lo: int, hi: int, message: str, optional: bool = False): # type: ignore[no-untyped-def]
159
+ def validate(value: str) -> str | None:
160
+ if optional and value.strip() == "":
161
+ return None
162
+ n = _js_int(value)
163
+ return None if n is not None and lo <= n <= hi else message
164
+
165
+ return validate
166
+
167
+
168
+ def _float_range(lo: float, hi: float, message: str): # type: ignore[no-untyped-def]
169
+ def validate(value: str) -> str | None:
170
+ if value.strip() == "":
171
+ return None
172
+ n = _js_float(value)
173
+ return None if n is not None and lo <= n <= hi else message
174
+
175
+ return validate
176
+
177
+
178
+ def _json_object_validator(kind: str, string_values: bool = False): # type: ignore[no-untyped-def]
179
+ def validate(value: str) -> str | None:
180
+ trimmed = value.strip()
181
+ if not trimmed:
182
+ return None
183
+ try:
184
+ parsed = json.loads(trimmed)
185
+ except ValueError:
186
+ return f"{kind} must be valid JSON"
187
+ if not isinstance(parsed, dict):
188
+ return f"{kind} must be a JSON object"
189
+ if string_values:
190
+ for k, v in parsed.items():
191
+ if not isinstance(v, str):
192
+ return f'Header "{k}" value must be a string'
193
+ return None
194
+
195
+ return validate
196
+
197
+
198
+ def _project() -> dict[str, Any]:
199
+ try:
200
+ io = ConfigIO()
201
+ if io.has_project():
202
+ return to_jsonable(io.read_project_spec())
203
+ except Exception: # noqa: BLE001
204
+ pass
205
+ return {}
206
+
207
+
208
+ def _prompt_mounts(kind: str, maximum: int, arn_validator: Any, network_mode: str | None) -> list[dict[str, str]]:
209
+ from agentcore.cli.commands.shared.filesystem_utils import validate_byo_mount_path
210
+
211
+ if network_mode != "VPC":
212
+ typer.echo(f"⚠ {kind} mounts require VPC network mode. Press Enter to skip or Esc to go back.")
213
+ example = "/mnt/efs-data" if kind == "EFS" else "/mnt/s3-data"
214
+ mounts: list[dict[str, str]] = []
215
+ while len(mounts) < maximum:
216
+
217
+ def validate_arn(value: str) -> str | None:
218
+ if not value:
219
+ return None
220
+ if network_mode != "VPC":
221
+ return f"{kind} mounts require VPC network mode"
222
+ return _err(arn_validator(value))
223
+
224
+ arn = interactive.text(
225
+ f"{kind} access point ARN {len(mounts) + 1}/{maximum} (press Enter to skip):", validate=validate_arn
226
+ ).strip()
227
+ if not arn:
228
+ break
229
+ path = interactive.text(
230
+ f"{kind} mount path for ...{arn[-20:]} (e.g. {example}):",
231
+ validate=lambda v: _err(validate_byo_mount_path(v)),
232
+ )
233
+ mounts.append({"accessPointArn": arn, "mountPath": path})
234
+ if len(mounts) >= maximum or not interactive.confirm(f"Add another {kind} mount?", default=False):
235
+ break
236
+ return mounts
237
+
238
+
239
+ def _prompt_skills(api_key_credentials: list[str]) -> list[dict[str, Any]]:
240
+ skills: list[dict[str, Any]] = []
241
+ while True:
242
+ source = interactive.select(
243
+ "Skill source type (Where is your skill located?)", _choices(SKILL_SOURCE_TYPE_OPTIONS)
244
+ )
245
+ if source == "path":
246
+ path = interactive.text(
247
+ "Path to an installed skill in the environment",
248
+ validate=lambda v: None if v.strip() else "Path is required",
249
+ )
250
+ skills.append({"path": path})
251
+ elif source == "s3":
252
+ uri = interactive.text(
253
+ "S3 URI (e.g., s3://my-bucket/skills/research)",
254
+ validate=lambda v: None if v.startswith("s3://") else "Must start with s3://",
255
+ )
256
+ skills.append({"s3Uri": uri})
257
+ elif source == "git":
258
+ git_url = interactive.text(
259
+ "Git repository URL (HTTPS)",
260
+ validate=lambda v: None if v.startswith("https://") else "Must be an HTTPS URL",
261
+ )
262
+ git_path = interactive.text("Subdirectory path within the repo (optional, press Enter to skip)")
263
+ credential = "skip"
264
+ if api_key_credentials:
265
+ credential = interactive.select(
266
+ "Git authentication (Select a credential for private repository access)",
267
+ [
268
+ *[C(n, n, "Use existing API key credential") for n in api_key_credentials],
269
+ C("Skip (no auth needed)", "skip", "Repository is publicly accessible"),
270
+ ],
271
+ )
272
+ username = interactive.text("Username for git auth (optional, press Enter to skip)")
273
+ skill: dict[str, Any] = {"gitUrl": git_url}
274
+ if git_path:
275
+ skill["gitPath"] = git_path
276
+ if credential != "skip":
277
+ skill["credentialName"] = credential
278
+ if username:
279
+ skill["username"] = username
280
+ skills.append(skill)
281
+ else:
282
+ paths = interactive.text(
283
+ "Filter paths (comma-separated globs, e.g., core-skills/* or specialized-skills/operations-skills/*) "
284
+ "or leave blank for all. See https://github.com/aws/agent-toolkit-for-aws/tree/main/skills"
285
+ )
286
+ skills.append({"awsSkills": _csv(paths)})
287
+ choice = interactive.select(
288
+ f"Add another skill? ({len(skills)} skill(s) configured)",
289
+ [
290
+ C("Add another skill", "add", "Add one more skill source"),
291
+ C("Done", "done", f"{len(skills)} skill(s) configured"),
292
+ ],
293
+ )
294
+ if choice != "add":
295
+ return skills
296
+
297
+
298
+ def run_add_harness_wizard(primitive: HarnessPrimitive) -> None: # noqa: C901 - one linear wizard, as upstream
299
+ from agentcore.cli.commands.add.agent_wizard import prompt_jwt_config
300
+ from agentcore.cli.commands.shared import filesystem_utils as fs
301
+ from agentcore.cli.commands.shared.vpc_utils import validate_vpc_id
302
+ from agentcore.primitives.harness import DEFAULT_BEDROCK_MANTLE_MODEL_ID, DEFAULT_MODEL_IDS
303
+ from agentcore.schema import MAX_EFS_MOUNTS, MAX_S3_MOUNTS, HarnessName
304
+
305
+ project = _project()
306
+ existing = [h["name"] for h in project.get("harnesses") or []]
307
+ api_key_credentials = [
308
+ c["name"] for c in project.get("credentials") or [] if c.get("authorizerType") == "ApiKeyCredentialProvider"
309
+ ]
310
+ cfg: dict[str, Any] = {}
311
+
312
+ cfg["name"] = interactive.text(
313
+ "Harness name",
314
+ default=generate_unique_name("MyHarness", existing),
315
+ validate=lambda v: first_issue(HarnessName, v) or ("Harness name already exists" if v in existing else None),
316
+ )
317
+ provider = interactive.select(
318
+ "Select model provider (Choose where to run your models)", _choices(MODEL_PROVIDER_OPTIONS)
319
+ )
320
+ cfg["modelProvider"] = provider
321
+ cfg["modelId"] = DEFAULT_MODEL_IDS[provider]
322
+
323
+ if provider in ("bedrock", "open_ai"):
324
+ description = (
325
+ "Choose the API format for OpenAI model invocation"
326
+ if provider == "open_ai"
327
+ else "Choose the API format for model invocation (Responses and ChatCompletions use Bedrock Mantle)"
328
+ )
329
+ options = OPENAI_API_FORMAT_OPTIONS if provider == "open_ai" else BEDROCK_API_FORMAT_OPTIONS
330
+ api_format = interactive.select(f"Select API format ({description})", _choices(options))
331
+ if provider == "bedrock":
332
+ mantle = api_format != "converse_stream"
333
+ if mantle:
334
+ cfg["apiFormat"] = api_format
335
+ cfg["modelId"] = DEFAULT_BEDROCK_MANTLE_MODEL_ID if mantle else DEFAULT_MODEL_IDS["bedrock"]
336
+ else:
337
+ cfg["apiFormat"] = api_format
338
+
339
+ if provider != "bedrock":
340
+ optional = provider == "lite_llm"
341
+ arn = interactive.text(
342
+ "API Key ARN (AgentCore Identity, optional — leave blank to skip)"
343
+ if optional
344
+ else "API Key ARN (AgentCore Identity)",
345
+ validate=lambda v: None if (optional and not v.strip()) or is_valid_arn(v) else ARN_VALIDATION_MESSAGE,
346
+ )
347
+ if arn:
348
+ cfg["apiKeyArn"] = arn
349
+
350
+ if provider == "lite_llm":
351
+ api_base = interactive.text("API base URL (optional — leave blank to use the provider default)")
352
+ if api_base:
353
+ cfg["apiBase"] = api_base
354
+ params = interactive.text(
355
+ 'Additional params as a JSON object (optional, e.g. {"reasoning_effort":"high"})',
356
+ validate=_json_object_validator("Additional params"),
357
+ ).strip()
358
+ if params:
359
+ cfg["additionalParams"] = json.loads(params)
360
+
361
+ container_mode = interactive.select(
362
+ "Custom environment (Optionally provide a custom container image for the harness runtime)",
363
+ _choices(CONTAINER_MODE_OPTIONS),
364
+ )
365
+ if container_mode == "uri":
366
+ cfg["containerUri"] = interactive.text(
367
+ "Container image URI (e.g., 123456789012.dkr.ecr.us-east-1.amazonaws.com/my-harness:latest)",
368
+ validate=lambda v: None if v.strip() else "Container URI is required",
369
+ )
370
+ elif container_mode == "dockerfile":
371
+ cfg["dockerfilePath"] = interactive.text(
372
+ "Path to Dockerfile", validate=lambda v: None if v.strip() else "Dockerfile path is required"
373
+ )
374
+
375
+ memory: dict[str, Any] = {
376
+ "mode": interactive.select("Memory (How should this harness handle memory?)", _choices(MEMORY_MODE_OPTIONS))
377
+ }
378
+ if memory["mode"] == "existing":
379
+
380
+ def validate_ref(value: str) -> str | None:
381
+ v = value.strip()
382
+ if v == "":
383
+ return "A memory name or ARN is required"
384
+ if v.startswith("arn:") and not is_valid_arn(v):
385
+ return ARN_VALIDATION_MESSAGE
386
+ return None
387
+
388
+ ref = interactive.text("Existing memory (name or ARN)", validate=validate_ref).strip()
389
+ memory["arn" if ref.startswith("arn:") else "name"] = ref
390
+
391
+ advanced_options = tuple(
392
+ o
393
+ for o in ADVANCED_SETTING_OPTIONS
394
+ if (o[0] != "memory-managed-tuning" or memory["mode"] == "managed")
395
+ and (o[0] != "memory-existing-tuning" or memory["mode"] == "existing")
396
+ )
397
+ advanced = interactive.checkbox(
398
+ "Advanced settings (optional) — Configure tools, network, lifecycle, execution limits, truncation, or "
399
+ "session storage",
400
+ _choices(advanced_options),
401
+ )
402
+
403
+ if "tools" in advanced:
404
+ selected = interactive.checkbox(
405
+ "Select tools for your harness (Choose built-in tools, MCP servers, or gateways)",
406
+ _choices(TOOL_SELECT_OPTIONS),
407
+ )
408
+ cfg["selectedTools"] = selected
409
+ if "remote_mcp" in selected:
410
+ cfg["mcpName"] = interactive.text(
411
+ "MCP server name", validate=lambda v: None if v.strip() else "MCP name is required"
412
+ )
413
+ cfg["mcpUrl"] = interactive.text(
414
+ "MCP server URL",
415
+ validate=lambda v: None if v.startswith(("http://", "https://")) else "Must be a valid URL",
416
+ )
417
+ headers = interactive.text(
418
+ 'MCP request headers as a JSON object (optional, e.g. {"X-Api-Key":"abc"})',
419
+ validate=_json_object_validator("Headers", string_values=True),
420
+ ).strip()
421
+ if headers:
422
+ cfg["mcpHeaders"] = json.loads(headers)
423
+ if "agentcore_gateway" in selected:
424
+ cfg["gatewayArn"] = interactive.text(
425
+ "Gateway ARN", validate=lambda v: None if is_valid_arn(v) else ARN_VALIDATION_MESSAGE
426
+ )
427
+ outbound = interactive.select(
428
+ "Gateway outbound auth (How should the harness authenticate when calling the gateway?)",
429
+ _choices(GATEWAY_OUTBOUND_AUTH_OPTIONS),
430
+ )
431
+ cfg["gatewayOutboundAuth"] = outbound
432
+ if outbound == "oauth":
433
+ cfg["gatewayProviderArn"] = interactive.text(
434
+ "Credential provider ARN", validate=lambda v: None if is_valid_arn(v) else ARN_VALIDATION_MESSAGE
435
+ )
436
+ cfg["gatewayScopes"] = _csv(
437
+ interactive.text(
438
+ "OAuth scopes (comma-separated)",
439
+ validate=lambda v: None if v.strip() else "At least one scope is required",
440
+ )
441
+ )
442
+
443
+ if "skills" in advanced:
444
+ cfg["skills"] = _prompt_skills(api_key_credentials)
445
+
446
+ if "auth" in advanced:
447
+ authorizer = interactive.select(
448
+ "Authorizer type (How will clients authenticate to this harness?)", _choices(AUTHORIZER_TYPE_OPTIONS)
449
+ )
450
+ cfg["authorizerType"] = authorizer
451
+ if authorizer == "CUSTOM_JWT":
452
+ cfg["jwtConfig"] = prompt_jwt_config()
453
+
454
+ if "network" in advanced:
455
+ network_mode = interactive.select(
456
+ "Network mode (Choose network deployment mode)", _choices(NETWORK_MODE_OPTIONS)
457
+ )
458
+ cfg["networkMode"] = network_mode
459
+ if network_mode == "VPC":
460
+ cfg["subnets"] = _csv(
461
+ interactive.text(
462
+ "Subnet IDs (comma-separated)",
463
+ validate=lambda v: _validate_id_list(v, SUBNET_ID_PATTERN, "subnet", "subnet-0abc123def456"),
464
+ )
465
+ )
466
+ cfg["securityGroups"] = _csv(
467
+ interactive.text(
468
+ "Security Group IDs (comma-separated)",
469
+ validate=lambda v: _validate_id_list(
470
+ v, SECURITY_GROUP_ID_PATTERN, "security group", "sg-0abc123def456"
471
+ ),
472
+ )
473
+ )
474
+ if container_mode == "dockerfile":
475
+ cfg["vpcId"] = interactive.text("VPC ID", validate=lambda v: _err(validate_vpc_id(v))).strip()
476
+
477
+ if "memory-managed-tuning" in advanced and memory["mode"] == "managed":
478
+ strategies = interactive.checkbox(
479
+ "Memory strategies (optional) — Leave all unselected to use the service default.",
480
+ _choices(MANAGED_STRATEGY_OPTIONS),
481
+ )
482
+ if strategies:
483
+ memory["strategies"] = strategies
484
+ expiry = interactive.text(
485
+ "Memory event expiry (days) — 3-365; press Enter for the default (30)",
486
+ validate=_int_range(3, 365, "Must be an integer between 3 and 365", optional=True),
487
+ )
488
+ if expiry.strip():
489
+ memory["eventExpiryDuration"] = _js_int(expiry)
490
+ kms = interactive.text(
491
+ "Memory KMS key ARN (optional)",
492
+ validate=lambda v: None if v.strip() == "" or is_valid_arn(v.strip()) else ARN_VALIDATION_MESSAGE,
493
+ ).strip()
494
+ if kms:
495
+ memory["encryptionKeyArn"] = kms
496
+
497
+ if "memory-existing-tuning" in advanced and memory["mode"] == "existing":
498
+ count = interactive.text(
499
+ "Memory messages count (optional)",
500
+ validate=_int_range(1, 2**53, "Must be a positive integer", optional=True),
501
+ )
502
+ if count.strip():
503
+ memory["messagesCount"] = _js_int(count)
504
+ top_k = interactive.text(
505
+ "Memory retrieval top K (optional)",
506
+ validate=_int_range(1, 2**53, "Must be a positive integer", optional=True),
507
+ )
508
+ if top_k.strip():
509
+ memory["topK"] = _js_int(top_k)
510
+ score = interactive.text(
511
+ "Memory relevance score (optional, 0.0-1.0)", validate=_float_range(0, 1, "Must be between 0.0 and 1.0")
512
+ )
513
+ if score.strip():
514
+ memory["relevanceScore"] = _num(_js_float(score))
515
+
516
+ if "allowed-tools" in advanced:
517
+
518
+ def validate_allowed(value: str) -> str | None:
519
+ items = _csv(value)
520
+ bad = next((t for t in items if len(t) > 64 or not _ALLOWED_TOOL.match(t)), None)
521
+ return f'Invalid pattern "{bad}" (use "*" or a tool name, max 64 chars)' if bad else None
522
+
523
+ allowed = interactive.text(
524
+ 'Allowed tools (comma-separated, optional, e.g. "*" or "browser,code-interpreter")',
525
+ validate=validate_allowed,
526
+ )
527
+ if _csv(allowed):
528
+ cfg["allowedTools"] = _csv(allowed)
529
+
530
+ if "lifecycle" in advanced:
531
+ cfg["idleTimeout"] = _js_int(
532
+ interactive.text(
533
+ "Idle timeout (seconds)", default="900", validate=_int_range(60, 28800, "Must be between 60 and 28800")
534
+ )
535
+ )
536
+
537
+ def validate_lifetime(value: str) -> str | None:
538
+ n = _js_int(value)
539
+ if n is None or n < 60 or n > 28800:
540
+ return "Must be between 60 and 28800"
541
+ if cfg.get("idleTimeout") is not None and n < cfg["idleTimeout"]:
542
+ return f"Max lifetime must be >= idle timeout ({cfg['idleTimeout']}s)"
543
+ return None
544
+
545
+ cfg["maxLifetime"] = _js_int(
546
+ interactive.text("Max lifetime (seconds)", default="28800", validate=validate_lifetime)
547
+ )
548
+
549
+ if "execution" in advanced:
550
+ positive = _int_range(1, 2**53, "Must be a positive number")
551
+ cfg["maxIterations"] = _js_int(interactive.text("Max iterations", default="10", validate=positive))
552
+ cfg["maxTokens"] = _js_int(interactive.text("Max tokens", default="4096", validate=positive))
553
+ cfg["timeoutSeconds"] = _js_int(interactive.text("Timeout (seconds)", default="300", validate=positive))
554
+ temperature = interactive.text(
555
+ "Temperature (optional, 0.0-2.0)", validate=_float_range(0, 2, "Must be between 0.0 and 2.0")
556
+ )
557
+ if temperature.strip():
558
+ cfg["temperature"] = _num(_js_float(temperature))
559
+ top_p = interactive.text(
560
+ "Top P (optional, 0.0-1.0)", validate=_float_range(0, 1, "Must be between 0.0 and 1.0")
561
+ )
562
+ if top_p.strip():
563
+ cfg["topP"] = _num(_js_float(top_p))
564
+ if provider == "gemini":
565
+ top_k = interactive.text(
566
+ "Top K (optional, 0-500, gemini only)",
567
+ validate=_int_range(0, 500, "Must be an integer between 0 and 500", optional=True),
568
+ )
569
+ if top_k.strip():
570
+ cfg["topK"] = _js_int(top_k)
571
+ model_max = interactive.text(
572
+ "Model max tokens (optional)", validate=_int_range(1, 2**53, "Must be a positive integer", optional=True)
573
+ )
574
+ if model_max.strip():
575
+ cfg["modelMaxTokens"] = _js_int(model_max)
576
+
577
+ if "truncation" in advanced:
578
+ cfg["truncationStrategy"] = interactive.select(
579
+ "Truncation strategy (How to manage context when it exceeds limits)", _choices(TRUNCATION_STRATEGY_OPTIONS)
580
+ )
581
+
582
+ if "session-storage" in advanced:
583
+ cfg["sessionStoragePath"] = interactive.text(
584
+ "Session storage mount path (e.g., /mnt/data/)",
585
+ default="/mnt/data/",
586
+ validate=lambda v: _err(fs.validate_byo_mount_path(v)),
587
+ )
588
+ efs = _prompt_mounts("EFS", MAX_EFS_MOUNTS, fs.validate_efs_access_point_arn, cfg.get("networkMode"))
589
+ if efs:
590
+ cfg["efsAccessPoints"] = efs
591
+ s3 = _prompt_mounts("S3 Files", MAX_S3_MOUNTS, fs.validate_s3_files_access_point_arn, cfg.get("networkMode"))
592
+ if s3:
593
+ cfg["s3AccessPoints"] = s3
594
+
595
+ _print_summary(cfg, memory)
596
+ if not interactive.confirm("Create this harness?", default=True):
597
+ typer.echo("Cancelled.")
598
+ return
599
+
600
+ options = {**cfg, **_to_memory_add_options(memory)}
601
+ result = primitive.add(primitive.add_options_from_dict(options))
602
+ if not result.success:
603
+ typer.echo("Failed to add harness", err=True)
604
+ typer.echo(get_error_message(result.error), err=True)
605
+ raise typer.Exit(1)
606
+ typer.echo(f"Added harness: {cfg['name']}")
607
+ typer.echo("Harness config written to app/. Deploy with `agentcore deploy`.")
608
+ if result.value.get("memoryMode") == "managed":
609
+ typer.echo(f"\nNote: {MANAGED_MEMORY_ADD_NOTICE}")
610
+
611
+
612
+ def _to_memory_add_options(memory: dict[str, Any]) -> dict[str, Any]:
613
+ """Port of memory-options.ts toMemoryAddOptions."""
614
+ if memory.get("mode") == "existing":
615
+ return {
616
+ "memoryMode": "existing",
617
+ "memoryName": memory.get("name"),
618
+ "memoryArn": memory.get("arn"),
619
+ "memoryActorId": memory.get("actorId"),
620
+ "messagesCount": memory.get("messagesCount"),
621
+ "memoryTopK": memory.get("topK"),
622
+ "memoryRelevanceScore": memory.get("relevanceScore"),
623
+ }
624
+ if memory.get("mode") == "managed":
625
+ return {
626
+ "memoryMode": "managed",
627
+ "memoryStrategies": memory.get("strategies"),
628
+ "memoryEventExpiryDays": memory.get("eventExpiryDuration"),
629
+ "memoryEncryptionKeyArn": memory.get("encryptionKeyArn"),
630
+ }
631
+ return {"memoryMode": "disabled"}
632
+
633
+
634
+ def _print_summary(cfg: dict[str, Any], memory: dict[str, Any]) -> None:
635
+ rows: list[tuple[str, Any]] = [
636
+ ("Name", cfg["name"]),
637
+ ("Model Provider", cfg["modelProvider"]),
638
+ ("Model ID", cfg["modelId"]),
639
+ ("API Format", cfg.get("apiFormat")),
640
+ ("API Key ARN", cfg.get("apiKeyArn")),
641
+ ("API Base URL", cfg.get("apiBase")),
642
+ ("Additional Params", json.dumps(cfg["additionalParams"]) if cfg.get("additionalParams") else None),
643
+ ]
644
+ if memory["mode"] == "managed":
645
+ strategies = memory.get("strategies")
646
+ titled = (
647
+ ", ".join(s[0] + s[1:].lower().replace("_", " ", 1) for s in strategies)
648
+ if strategies
649
+ else "default strategies"
650
+ )
651
+ rows.append(("Memory", f"Managed ({titled})"))
652
+ if memory.get("eventExpiryDuration") is not None:
653
+ rows.append(("Memory Event Expiry", f"{memory['eventExpiryDuration']} days"))
654
+ rows.append(("Memory KMS Key", memory.get("encryptionKeyArn")))
655
+ elif memory["mode"] == "existing":
656
+ rows.append(("Memory", f"Existing ({memory.get('arn') or memory.get('name') or '—'})"))
657
+ rows.append(("Memory Messages Count", memory.get("messagesCount")))
658
+ rows.append(("Memory Retrieval Top K", memory.get("topK")))
659
+ rows.append(("Memory Relevance Score", memory.get("relevanceScore")))
660
+ else:
661
+ rows.append(("Memory", "No memory"))
662
+ if cfg.get("allowedTools"):
663
+ rows.append(("Allowed Tools", ", ".join(cfg["allowedTools"])))
664
+ if cfg.get("authorizerType"):
665
+ rows.append(("Auth Type", _title(AUTHORIZER_TYPE_OPTIONS, cfg["authorizerType"])))
666
+ jwt = cfg.get("jwtConfig")
667
+ if cfg.get("authorizerType") == "CUSTOM_JWT" and jwt:
668
+ rows.append(("Discovery URL", jwt.discovery_url))
669
+ for label, values in (
670
+ ("Allowed Audience", jwt.allowed_audience),
671
+ ("Allowed Clients", jwt.allowed_clients),
672
+ ("Allowed Scopes", jwt.allowed_scopes),
673
+ ):
674
+ if values:
675
+ rows.append((label, ", ".join(values)))
676
+ if jwt.custom_claims:
677
+ rows.append(("Custom Claims", f"{len(jwt.custom_claims)} claim(s) configured"))
678
+ if jwt.client_id:
679
+ rows.append(("Harness Credential", compute_managed_oauth_credential_name(cfg["name"])))
680
+ if cfg.get("selectedTools"):
681
+ rows.append(("Tools", ", ".join(_title(TOOL_SELECT_OPTIONS, t) for t in cfg["selectedTools"])))
682
+ if cfg.get("mcpName"):
683
+ rows.append(("MCP Server", f"{cfg['mcpName']} ({cfg.get('mcpUrl')})"))
684
+ if cfg.get("mcpHeaders"):
685
+ rows.append(("MCP Headers", json.dumps(cfg["mcpHeaders"])))
686
+ rows.append(("Gateway ARN", cfg.get("gatewayArn")))
687
+ if cfg.get("gatewayOutboundAuth"):
688
+ rows.append(("Gateway Auth", _title(GATEWAY_OUTBOUND_AUTH_OPTIONS, cfg["gatewayOutboundAuth"])))
689
+ if cfg.get("gatewayOutboundAuth") == "oauth":
690
+ rows.append(("Provider ARN", cfg.get("gatewayProviderArn")))
691
+ rows.append(("OAuth Scopes", ",".join(cfg.get("gatewayScopes") or [])))
692
+ for i, skill in enumerate(cfg.get("skills") or []):
693
+ aws = skill.get("awsSkills")
694
+ aws_label = f"aws-skills ({', '.join(aws) if aws else 'all'})" if aws is not None else None
695
+ rows.append((f"Skill {i + 1}", skill.get("s3Uri") or skill.get("gitUrl") or skill.get("path") or aws_label))
696
+ for label, key in (
697
+ ("Container URI", "containerUri"),
698
+ ("Dockerfile", "dockerfilePath"),
699
+ ("Network Mode", "networkMode"),
700
+ ("Subnets", "subnets"),
701
+ ("Security Groups", "securityGroups"),
702
+ ("VPC ID", "vpcId"),
703
+ ("Idle Timeout", "idleTimeout"),
704
+ ("Max Lifetime", "maxLifetime"),
705
+ ("Max Iterations", "maxIterations"),
706
+ ("Max Tokens", "maxTokens"),
707
+ ("Timeout", "timeoutSeconds"),
708
+ ("Temperature", "temperature"),
709
+ ("Top P", "topP"),
710
+ ("Top K", "topK"),
711
+ ("Model Max Tokens", "modelMaxTokens"),
712
+ ("Truncation", "truncationStrategy"),
713
+ ("Session Storage", "sessionStoragePath"),
714
+ ):
715
+ value = cfg.get(key)
716
+ rows.append((label, ", ".join(value) if isinstance(value, list) else value))
717
+ for mount in cfg.get("efsAccessPoints") or []:
718
+ rows.append(("EFS Mount", f"{mount['accessPointArn']} -> {mount['mountPath']}"))
719
+ for mount in cfg.get("s3AccessPoints") or []:
720
+ rows.append(("S3 Files Mount", f"{mount['accessPointArn']} -> {mount['mountPath']}"))
721
+ for label, value in rows:
722
+ if value not in (None, "", []):
723
+ typer.echo(f" {label}: {value}")
724
+
725
+
726
+ __all__ = ["run_add_harness_wizard"]