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,605 @@
1
+ """Payment manager add/remove (port of src/cli/primitives/PaymentManagerPrimitive.ts).
2
+
3
+ Adding a manager also wires the payments capability shim into eligible (Python Strands HTTP)
4
+ agents. Connectors are managed by ``payment_connector``.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import os
10
+ import re
11
+ import sys
12
+ from dataclasses import dataclass
13
+ from typing import Any
14
+
15
+ import typer
16
+
17
+ from agentcore.cli import interactive
18
+ from agentcore.cli.constants import ANSI
19
+ from agentcore.cli.errors import get_error_message
20
+ from agentcore.lib import remove_env_vars
21
+ from agentcore.lib.errors.types import to_error
22
+ from agentcore.lib.result import Err, Ok, serialize_result
23
+ from agentcore.lib.schemas.io.config_io import to_jsonable
24
+ from agentcore.lib.schemas.io.path_resolver import find_config_root
25
+ from agentcore.primitives.base import (
26
+ SOURCE_CODE_NOTE,
27
+ BasePrimitive,
28
+ RemovableResource,
29
+ RemovalPreview,
30
+ SchemaChange,
31
+ emit_json,
32
+ )
33
+ from agentcore.primitives.credential_utils import (
34
+ compute_payment_credential_env_var_names,
35
+ compute_stripe_privy_credential_env_var_names,
36
+ )
37
+ from agentcore.primitives.payment_eligible import is_payment_eligible_runtime
38
+ from agentcore.schema import DEFAULT_AUTO_PAYMENT, DEFAULT_SPEND_LIMIT
39
+
40
+ PAYMENT_AUTHORIZER_TYPES = ("AWS_IAM", "CUSTOM_JWT")
41
+ _IMPORT_LINE = "from capabilities.payments.payments import create_payments_plugin, PAYMENT_SYSTEM_PROMPT"
42
+
43
+
44
+ def compute_import_insertion_point(source: str) -> int:
45
+ """Offset just after any shebang/comments, module docstring and ``from __future__`` imports."""
46
+ pos, length = 0, len(source)
47
+ while pos < length:
48
+ if source[pos] == "\n":
49
+ pos += 1
50
+ continue
51
+ line_end = source.find("\n", pos)
52
+ line_end_pos = length if line_end == -1 else line_end
53
+ line = source[pos:line_end_pos]
54
+ trimmed = line.strip()
55
+ if trimmed.startswith("#"):
56
+ pos = line_end_pos + 1
57
+ continue
58
+ if trimmed.startswith(('"""', "'''")):
59
+ quote = trimmed[:3]
60
+ rest = trimmed[3:]
61
+ if rest.endswith(quote) and len(rest) >= 3:
62
+ pos = line_end_pos + 1
63
+ continue
64
+ close = source.find(quote, pos + 3)
65
+ if close == -1:
66
+ break
67
+ after = source.find("\n", close + 3)
68
+ pos = length if after == -1 else after + 1
69
+ continue
70
+ if re.match(r"^from __future__ import\b", trimmed):
71
+ open_paren = line.find("(")
72
+ if open_paren != -1 and ")" not in line[open_paren:]:
73
+ close_paren = source.find(")", pos)
74
+ if close_paren == -1:
75
+ break
76
+ after = source.find("\n", close_paren)
77
+ pos = length if after == -1 else after + 1
78
+ else:
79
+ pos = line_end_pos + 1
80
+ continue
81
+ break
82
+ return pos
83
+
84
+
85
+ def _plugin_setup(indent: str) -> list[str]:
86
+ return [
87
+ f"{indent}# Payment plugin (per-invocation — different user/instrument/session per request)",
88
+ f'{indent}user_id = payload.get("user_id") or getattr(context, "user_id", "default-user")',
89
+ f'{indent}instrument_id = payload.get("payment_instrument_id")',
90
+ f'{indent}session_id = payload.get("payment_session_id")',
91
+ f"{indent}payments_plugin = create_payments_plugin(user_id, instrument_id, session_id)",
92
+ f"{indent}plugins = [payments_plugin] if payments_plugin else []",
93
+ "",
94
+ ]
95
+
96
+
97
+ def wire_payment_capability(config_root: str, code_location: str) -> bool:
98
+ """Copy the payments capability into a Strands agent and patch its main.py (idempotent)."""
99
+ from agentcore.templates.template_root import get_template_path
100
+
101
+ project_root = os.path.dirname(config_root)
102
+ agent_dir = os.path.abspath(os.path.join(project_root, code_location))
103
+ cap_dir = os.path.join(agent_dir, "capabilities", "payments")
104
+ main_path = os.path.join(agent_dir, "main.py")
105
+ if not os.path.exists(main_path):
106
+ return False
107
+ with open(main_path, encoding="utf-8") as fh:
108
+ main = fh.read()
109
+
110
+ is_strands = bool(re.search(r"^from strands(\.|\s)", main, re.M)) or "from strands import" in main
111
+ if not is_strands:
112
+ return False
113
+
114
+ template_dir = get_template_path("python", "http", "strands", "capabilities", "payments")
115
+ if not template_dir.is_dir():
116
+ return False
117
+
118
+ if not os.path.exists(os.path.join(cap_dir, "payments.py")):
119
+ os.makedirs(cap_dir, exist_ok=True)
120
+ with open(os.path.join(cap_dir, "payments.py"), "w", encoding="utf-8") as fh:
121
+ fh.write((template_dir / "payments.py").read_text(encoding="utf-8"))
122
+ for init_path in (os.path.join(cap_dir, "__init__.py"), os.path.join(agent_dir, "capabilities", "__init__.py")):
123
+ if not os.path.exists(init_path):
124
+ with open(init_path, "w", encoding="utf-8"):
125
+ pass
126
+
127
+ if "create_payments_plugin" in main:
128
+ return True
129
+
130
+ insert = compute_import_insertion_point(main)
131
+ patched = main[:insert] + _IMPORT_LINE + "\n" + main[insert:]
132
+
133
+ agent_call = re.search(r"^([^\S\n]*)agent = get_or_create_agent\(\)[ \t]*(#[^\n]*)?$", patched, re.M)
134
+ if agent_call:
135
+ indent = agent_call.group(1)
136
+ uses_config_bundle = bool(re.search(r"\bConfigBundleHook\b", patched))
137
+ replacement = "\n".join(
138
+ [
139
+ *_plugin_setup(indent),
140
+ f"{indent}agent = Agent(",
141
+ f"{indent} model=load_model(),",
142
+ f"{indent} system_prompt=DEFAULT_SYSTEM_PROMPT + PAYMENT_SYSTEM_PROMPT,",
143
+ f"{indent} tools=tools,",
144
+ f"{indent} plugins=plugins,",
145
+ *([f"{indent} hooks=[ConfigBundleHook()],"] if uses_config_bundle else []),
146
+ f"{indent})",
147
+ ]
148
+ )
149
+ patched = patched[: agent_call.start()] + replacement + patched[agent_call.end() :]
150
+ singleton = re.compile(
151
+ r"^_agent(?:\s*:[^=\n]+)?\s*=\s*None\n\n+def get_or_create_agent\(\):[\s\S]+?return _agent\n", re.M
152
+ )
153
+ before = patched
154
+ patched = singleton.sub("", patched, count=1)
155
+ if patched == before:
156
+ raise Exception(
157
+ f"Could not safely auto-wire payments into {main_path}: the agent= call was replaced but the cached "
158
+ "`_agent` / `get_or_create_agent` definition has an unrecognised shape. Edit main.py manually — see "
159
+ "docs/payments.md for the expected pattern."
160
+ )
161
+ else:
162
+ byo = re.search(r"^(\s*)(agent = Agent\()", patched, re.M)
163
+ if byo:
164
+ indent = byo.group(1)
165
+ setup = "\n".join(
166
+ [
167
+ *_plugin_setup(indent),
168
+ f"{indent}# TODO: Add plugins=plugins to your Agent() constructor below",
169
+ f"{indent}{byo.group(2)}",
170
+ ]
171
+ )
172
+ patched = patched[: byo.start()] + setup + patched[byo.end() :]
173
+
174
+ with open(main_path, "w", encoding="utf-8") as fh:
175
+ fh.write(patched)
176
+ return True
177
+
178
+
179
+ @dataclass
180
+ class AddPaymentManagerOptions:
181
+ name: str
182
+ authorizer_type: str = "AWS_IAM"
183
+ discovery_url: str | None = None
184
+ allowed_clients: list[str] | None = None
185
+ allowed_audience: list[str] | None = None
186
+ allowed_scopes: list[str] | None = None
187
+ description: str | None = None
188
+ auto_payment: bool | None = None
189
+ default_spend_limit: str | None = None
190
+ payment_tool_allowlist: list[str] | None = None
191
+ network_preferences: list[str] | None = None
192
+
193
+
194
+ def _parse_list(value: str | None) -> list[str] | None:
195
+ return [s.strip() for s in value.split(",") if s.strip()] if value else None
196
+
197
+
198
+ def _cleanup_credential_env(credential_name: str, provider: str | None, config_root: str | None) -> None:
199
+ try:
200
+ if provider == "StripePrivy":
201
+ v = compute_stripe_privy_credential_env_var_names(credential_name)
202
+ remove_env_vars([v.app_id, v.app_secret, v.authorization_private_key, v.authorization_id], config_root)
203
+ else:
204
+ p = compute_payment_credential_env_var_names(credential_name)
205
+ remove_env_vars([p.api_key_id, p.api_key_secret, p.wallet_secret], config_root)
206
+ except Exception: # noqa: BLE001 - best-effort cleanup
207
+ pass
208
+
209
+
210
+ class PaymentManagerPrimitive(BasePrimitive):
211
+ kind = "payment-manager"
212
+ label = "Payment Manager"
213
+
214
+ def _project(self) -> dict[str, Any]:
215
+ project = to_jsonable(self.read_project_spec())
216
+ if project.get("payments") is None:
217
+ project["payments"] = []
218
+ return project
219
+
220
+ def add(self, options: AddPaymentManagerOptions) -> Ok[dict[str, Any]] | Err[Exception]:
221
+ try:
222
+ project = self._project()
223
+ if any(p["name"] == options.name for p in project["payments"]):
224
+ raise ValueError(f'Payment manager "{options.name}" already exists.')
225
+ if options.authorizer_type == "CUSTOM_JWT" and not options.discovery_url:
226
+ return Err(Exception("--discovery-url is required when --authorizer-type is CUSTOM_JWT"))
227
+
228
+ manager: dict[str, Any] = {"name": options.name, "authorizerType": options.authorizer_type}
229
+ if options.authorizer_type == "CUSTOM_JWT":
230
+ jwt: dict[str, Any] = {"discoveryUrl": options.discovery_url}
231
+ if options.allowed_clients is not None:
232
+ jwt["allowedClients"] = options.allowed_clients
233
+ if options.allowed_audience is not None:
234
+ jwt["allowedAudience"] = options.allowed_audience
235
+ if options.allowed_scopes is not None:
236
+ jwt["allowedScopes"] = options.allowed_scopes
237
+ manager["authorizerConfiguration"] = {"customJWTAuthorizer": jwt}
238
+ manager["connectors"] = []
239
+ if options.description:
240
+ manager["description"] = options.description
241
+ auto_payment = DEFAULT_AUTO_PAYMENT if options.auto_payment is None else options.auto_payment
242
+ spend_limit = (
243
+ options.default_spend_limit if options.default_spend_limit is not None else DEFAULT_SPEND_LIMIT
244
+ )
245
+ manager["autoPayment"] = auto_payment
246
+ manager["defaultSpendLimit"] = spend_limit
247
+ if options.payment_tool_allowlist:
248
+ manager["paymentToolAllowlist"] = options.payment_tool_allowlist
249
+ if options.network_preferences:
250
+ manager["networkPreferences"] = options.network_preferences
251
+ project["payments"].append(manager)
252
+ self.write_project_spec(project)
253
+
254
+ config_root = find_config_root()
255
+ skipped: list[str] = []
256
+ if config_root:
257
+ for runtime in project.get("runtimes") or []:
258
+ if not is_payment_eligible_runtime(runtime):
259
+ skipped.append(runtime["name"])
260
+ continue
261
+ if not wire_payment_capability(config_root, runtime.get("codeLocation", "")):
262
+ skipped.append(runtime["name"])
263
+
264
+ warning = (
265
+ f'auto-payment is ENABLED for manager "{options.name}". Agents will automatically settle '
266
+ "402 Payment Required responses up to the per-session spend limit "
267
+ f"(${spend_limit}) with no human approval. "
268
+ "Re-run with --auto-payment false to require manual approval."
269
+ if auto_payment
270
+ else None
271
+ )
272
+ return Ok(
273
+ {
274
+ "managerName": options.name,
275
+ "skippedRuntimes": skipped,
276
+ "autoPaymentWarning": warning,
277
+ }
278
+ )
279
+ except Exception as exc: # noqa: BLE001
280
+ return Err(to_error(exc))
281
+
282
+ def remove(self, name: str) -> Ok[None] | Err[Exception]:
283
+ try:
284
+ project = self._project()
285
+ payments = project["payments"]
286
+ index = next((i for i, p in enumerate(payments) if p["name"] == name), -1)
287
+ if index == -1:
288
+ return Err(Exception(f'Payment manager "{name}" not found.'))
289
+ manager = payments[index]
290
+ connector_info = [
291
+ (c.get("credentialName"), c.get("provider"))
292
+ for c in manager.get("connectors") or []
293
+ if c.get("provisionMode") != "QUICK_CREATE"
294
+ ]
295
+ payments.pop(index)
296
+
297
+ def still_referenced(credential: str) -> bool:
298
+ return any(c.get("credentialName") == credential for m in payments for c in m.get("connectors") or [])
299
+
300
+ for credential, _ in connector_info:
301
+ if not still_referenced(credential):
302
+ project["credentials"] = [c for c in project.get("credentials") or [] if c["name"] != credential]
303
+ self.write_project_spec(project)
304
+
305
+ config_root = self.config_io.get_config_root()
306
+ for credential, provider in connector_info:
307
+ if not still_referenced(credential):
308
+ _cleanup_credential_env(credential, provider, config_root)
309
+ return Ok(None)
310
+ except Exception as exc: # noqa: BLE001
311
+ return Err(to_error(exc))
312
+
313
+ def preview_remove(self, name: str) -> RemovalPreview:
314
+ project = self._project()
315
+ manager = next((p for p in project["payments"] if p["name"] == name), None)
316
+ if manager is None:
317
+ raise Exception(f'Payment manager "{name}" not found.')
318
+ connectors = manager.get("connectors") or []
319
+ summary = [f"Removing payment manager: {name}"]
320
+ if connectors:
321
+ summary.append(f"Note: {len(connectors)} connector(s) within this manager will also be removed")
322
+ for c in connectors:
323
+ summary.append(
324
+ f" - Connector: {c['name']} (Quick Create)"
325
+ if c.get("provisionMode") == "QUICK_CREATE"
326
+ else f" - Connector: {c['name']} (credential: {c.get('credentialName')})"
327
+ )
328
+ for c in connectors:
329
+ if c.get("provisionMode") == "QUICK_CREATE":
330
+ continue
331
+ credential = c.get("credentialName")
332
+ shared = any(
333
+ m["name"] != name
334
+ and any(
335
+ o.get("provisionMode") != "QUICK_CREATE" and o.get("credentialName") == credential
336
+ for o in m.get("connectors") or []
337
+ )
338
+ for m in project["payments"]
339
+ )
340
+ summary.append(
341
+ f'Credential "{credential}" is shared by other managers and will be kept'
342
+ if shared
343
+ else f'Associated credential "{credential}" will also be removed'
344
+ )
345
+ after = {**project, "payments": [p for p in project["payments"] if p["name"] != name]}
346
+ return RemovalPreview(summary, [], [SchemaChange("agentcore/agentcore.json", project, after)])
347
+
348
+ def get_removable(self) -> list[RemovableResource]:
349
+ try:
350
+ return [RemovableResource(p["name"]) for p in self._project()["payments"]]
351
+ except Exception: # noqa: BLE001
352
+ return []
353
+
354
+ def get_existing_managers(self) -> list[str]:
355
+ return [r.name for r in self.get_removable()]
356
+
357
+ # --- CLI ----------------------------------------------------------------------------
358
+
359
+ def register_commands(self, add_app: typer.Typer, remove_app: typer.Typer) -> None:
360
+ from agentcore.cli.commands.add._commander import optional_value, optional_value_command
361
+
362
+ @add_app.command(
363
+ "payment-manager",
364
+ help="Add a payment manager to the project",
365
+ cls=optional_value_command("--auto-payment"),
366
+ )
367
+ def add_command(
368
+ name: str | None = typer.Option(None, "--name", help="Payment manager name [non-interactive]"),
369
+ authorizer_type: str | None = typer.Option(
370
+ None,
371
+ "--authorizer-type",
372
+ help="Authorizer type: AWS_IAM or CUSTOM_JWT (default: AWS_IAM) [non-interactive]",
373
+ ),
374
+ discovery_url: str | None = typer.Option(
375
+ None, "--discovery-url", help="OIDC discovery URL (required for CUSTOM_JWT) [non-interactive]"
376
+ ),
377
+ allowed_clients: str | None = typer.Option(
378
+ None,
379
+ "--allowed-clients",
380
+ help="Comma-separated allowed client IDs (for CUSTOM_JWT) [non-interactive]",
381
+ ),
382
+ allowed_audience: str | None = typer.Option(
383
+ None,
384
+ "--allowed-audience",
385
+ help="Comma-separated allowed audiences (for CUSTOM_JWT) [non-interactive]",
386
+ ),
387
+ allowed_scopes: str | None = typer.Option(
388
+ None, "--allowed-scopes", help="Comma-separated allowed scopes (for CUSTOM_JWT) [non-interactive]"
389
+ ),
390
+ auto_payment: str | None = typer.Option(
391
+ None,
392
+ "--auto-payment",
393
+ metavar="[VALUE]",
394
+ help="Enable auto payment: true or false (default: true) [non-interactive]",
395
+ ),
396
+ default_spend_limit: str | None = typer.Option(
397
+ None,
398
+ "--default-spend-limit",
399
+ help="Spend cap (USD) for sessions created by `invoke --auto-session` ONLY; not a deployed-agent "
400
+ "budget (default: 10.00) [non-interactive]",
401
+ ),
402
+ tool_allowlist: str | None = typer.Option(
403
+ None, "--tool-allowlist", help="Comma-separated tool names eligible for payment [non-interactive]"
404
+ ),
405
+ network_preferences: str | None = typer.Option(
406
+ None,
407
+ "--network-preferences",
408
+ help="Comma-separated network identifiers e.g. eip155:84532 [non-interactive]",
409
+ ),
410
+ description: str | None = typer.Option(
411
+ None, "--description", help="Payment manager description [non-interactive]"
412
+ ),
413
+ as_json: bool = typer.Option(False, "--json", help="Output as JSON [non-interactive]"),
414
+ ) -> None:
415
+ auto = optional_value(auto_payment)
416
+ try:
417
+ if not find_config_root():
418
+ typer.echo("No agentcore project found. Run `agentcore create` first.", err=True)
419
+ raise typer.Exit(1)
420
+ if name is None and not authorizer_type and not as_json:
421
+ interactive.require_tty()
422
+ self.add_interactive()
423
+ raise typer.Exit(0)
424
+ self._run_add_cli(
425
+ name,
426
+ authorizer_type,
427
+ discovery_url,
428
+ allowed_clients,
429
+ allowed_audience,
430
+ allowed_scopes,
431
+ auto,
432
+ default_spend_limit,
433
+ tool_allowlist,
434
+ network_preferences,
435
+ description,
436
+ as_json,
437
+ )
438
+ except typer.Exit:
439
+ raise
440
+ except Exception as exc: # noqa: BLE001
441
+ if as_json:
442
+ emit_json({"success": False, "error": get_error_message(exc)})
443
+ else:
444
+ typer.echo(f"Error: {get_error_message(exc)}", err=True)
445
+ raise typer.Exit(1) from None
446
+
447
+ @remove_app.command("payment-manager", help="Remove a payment manager from the project")
448
+ def remove_command(
449
+ name: str | None = typer.Option(None, "--name", help="Name of resource to remove [non-interactive]"),
450
+ yes: bool = typer.Option(False, "-y", "--yes", help="Skip confirmation prompt [non-interactive]"),
451
+ as_json: bool = typer.Option(False, "--json", help="Output as JSON [non-interactive]"),
452
+ ) -> None:
453
+ _run_named_remove(self, name, yes, as_json, name)
454
+
455
+ def _run_add_cli(
456
+ self,
457
+ name: str | None,
458
+ authorizer_type: str | None,
459
+ discovery_url: str | None,
460
+ allowed_clients: str | None,
461
+ allowed_audience: str | None,
462
+ allowed_scopes: str | None,
463
+ auto_payment: str | bool | None,
464
+ default_spend_limit: str | None,
465
+ tool_allowlist: str | None,
466
+ network_preferences: str | None,
467
+ description: str | None,
468
+ as_json: bool,
469
+ ) -> None:
470
+ from agentcore.cli.commands.add._common import first_issue
471
+ from agentcore.schema import PaymentManagerName
472
+
473
+ def fail(error: str) -> None:
474
+ if as_json:
475
+ emit_json({"success": False, "error": error})
476
+ else:
477
+ typer.echo(error, err=True)
478
+ raise typer.Exit(1)
479
+
480
+ if not name:
481
+ fail("--name is required")
482
+ issue = first_issue(PaymentManagerName, name)
483
+ if issue:
484
+ fail(f"Invalid name: {issue}")
485
+ resolved_auth = authorizer_type if authorizer_type is not None else "AWS_IAM"
486
+ if resolved_auth not in PAYMENT_AUTHORIZER_TYPES:
487
+ fail(f'Invalid authorizer type "{authorizer_type}". Valid: AWS_IAM, CUSTOM_JWT')
488
+ if default_spend_limit is not None:
489
+ from agentcore.primitives._harness_cli import _js_number
490
+
491
+ num = _js_number(default_spend_limit)
492
+ if num is None or num != num or num < 0:
493
+ fail('Invalid --default-spend-limit: must be a valid non-negative number (e.g., "10.00")')
494
+
495
+ auto: bool | None = None
496
+ if auto_payment is not None:
497
+ val = "true" if auto_payment is True else str(auto_payment).lower()
498
+ if val not in ("true", "false", "yes", "no", "1", "0", "on", "off"):
499
+ raise Exception(f'Invalid --auto-payment value "{auto_payment}". Use true or false.')
500
+ auto = val not in ("false", "no", "0", "off")
501
+
502
+ result = self.add(
503
+ AddPaymentManagerOptions(
504
+ name=name or "",
505
+ authorizer_type=resolved_auth,
506
+ discovery_url=discovery_url,
507
+ allowed_clients=_parse_list(allowed_clients),
508
+ allowed_audience=_parse_list(allowed_audience),
509
+ allowed_scopes=_parse_list(allowed_scopes),
510
+ auto_payment=auto,
511
+ default_spend_limit=default_spend_limit,
512
+ payment_tool_allowlist=_parse_list(tool_allowlist),
513
+ network_preferences=_parse_list(network_preferences),
514
+ description=description,
515
+ )
516
+ )
517
+ if as_json:
518
+ if result.success:
519
+ payload = {k: v for k, v in result.value.items() if k != "autoPaymentWarning"}
520
+ emit_json(serialize_result(Ok(payload)))
521
+ else:
522
+ emit_json(serialize_result(result))
523
+ elif result.success:
524
+ value = result.value
525
+ typer.echo(f"Added payment manager '{value['managerName']}'")
526
+ if value.get("autoPaymentWarning"):
527
+ sys.stderr.write(f"{ANSI.yellow}Warning: {value['autoPaymentWarning']}{ANSI.reset}\n")
528
+ if value.get("skippedRuntimes"):
529
+ sys.stderr.write(
530
+ "\nWarning: payment capability auto-wiring skipped for non-Strands runtime(s): "
531
+ f"{', '.join(value['skippedRuntimes'])}.\n"
532
+ )
533
+ sys.stderr.write(
534
+ "Payments are only auto-wired into Strands agents today. You will need to wire payment plugins "
535
+ "manually for these runtimes.\n"
536
+ )
537
+ else:
538
+ typer.echo("\nPayment capability code has been added to your agent(s).")
539
+ typer.echo(
540
+ f"Add a payment connector with `agentcore add payment-connector --manager {value['managerName']}`"
541
+ )
542
+ else:
543
+ typer.echo(get_error_message(result.error), err=True)
544
+ raise typer.Exit(0 if result.success else 1)
545
+
546
+ # --- interactive (port of tui/screens/payment AddPaymentFlow, manager path) ---------
547
+
548
+ def add_interactive(self) -> None:
549
+ from agentcore.primitives._payment_wizard import run_add_payment_manager_wizard
550
+
551
+ run_add_payment_manager_wizard(self)
552
+
553
+
554
+ def _run_named_remove(
555
+ primitive: BasePrimitive, name: str | None, yes: bool, as_json: bool, key: str | None, label_name: str | None = None
556
+ ) -> None:
557
+ """Payment remove CLI: like the base remove, but plain text (not JSON) without --json."""
558
+ try:
559
+ if not find_config_root():
560
+ typer.echo("No agentcore project found. Run `agentcore create` first.", err=True)
561
+ raise typer.Exit(1)
562
+ if name or yes or as_json:
563
+ if not name:
564
+ if as_json:
565
+ emit_json({"success": False, "error": "--name is required"})
566
+ else:
567
+ typer.echo("--name is required", err=True)
568
+ raise typer.Exit(1)
569
+ result = primitive.remove(key or name)
570
+ if as_json:
571
+ emit_json(
572
+ {
573
+ "success": result.success,
574
+ "resourceType": primitive.kind,
575
+ "resourceName": name,
576
+ "message": f"Removed {primitive.label.lower()} '{name}'" if result.success else None,
577
+ "note": SOURCE_CODE_NOTE if result.success else None,
578
+ "error": None if result.success else get_error_message(result.error),
579
+ }
580
+ )
581
+ elif result.success:
582
+ typer.echo(f"Removed {primitive.label.lower()} '{name}'")
583
+ else:
584
+ typer.echo(get_error_message(result.error), err=True)
585
+ raise typer.Exit(0 if result.success else 1)
586
+ interactive.require_tty()
587
+ primitive.remove_interactive()
588
+ except typer.Exit:
589
+ raise
590
+ except Exception as exc: # noqa: BLE001
591
+ if as_json:
592
+ emit_json({"success": False, "error": get_error_message(exc)})
593
+ else:
594
+ typer.echo(f"Error: {get_error_message(exc)}", err=True)
595
+ raise typer.Exit(1) from None
596
+
597
+
598
+ __all__ = [
599
+ "AddPaymentManagerOptions",
600
+ "PaymentManagerPrimitive",
601
+ "compute_import_insertion_point",
602
+ "wire_payment_capability",
603
+ ]
604
+
605
+ PRIMITIVE = PaymentManagerPrimitive()
@@ -0,0 +1,68 @@
1
+ """Client-side format validation for payment connector secrets (port of payment-validation.ts).
2
+
3
+ Each validator returns ``True`` when valid or a human-readable error string.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ import base64
9
+ import re
10
+ from typing import Literal
11
+
12
+ _BASE64 = re.compile(r"^[A-Za-z0-9+/]+=*$")
13
+ ED25519_MIN_BYTES = 32
14
+ ED25519_MAX_BYTES = 64
15
+ P256_MIN_BYTES = 100
16
+ P256_MAX_BYTES = 200
17
+ WALLET_AUTH_PREFIX = "wallet-auth:"
18
+
19
+
20
+ def _decode_base64(value: str) -> bytes | None:
21
+ """Node's lenient ``Buffer.from(value, 'base64')`` after the character-set check."""
22
+ if not _BASE64.match(value):
23
+ return None
24
+ stripped = value.rstrip("=")
25
+ usable = len(stripped) - (len(stripped) % 4 == 1) # a lone trailing sextet decodes to nothing
26
+ stripped = stripped[:usable]
27
+ return base64.b64decode(stripped + "=" * (-len(stripped) % 4))
28
+
29
+
30
+ def validate_api_key_secret(value: str) -> Literal[True] | str:
31
+ decoded = _decode_base64(value.strip())
32
+ if decoded is None:
33
+ return "apiKeySecret must be a base64-encoded Ed25519 private key"
34
+ if not ED25519_MIN_BYTES <= len(decoded) <= ED25519_MAX_BYTES:
35
+ return "apiKeySecret must be a base64-encoded Ed25519 private key (unexpected length)"
36
+ return True
37
+
38
+
39
+ def validate_wallet_secret(value: str) -> Literal[True] | str:
40
+ decoded = _decode_base64(value.strip())
41
+ if decoded is None:
42
+ return "walletSecret must be a base64-encoded EC P-256 private key"
43
+ if not P256_MIN_BYTES <= len(decoded) <= P256_MAX_BYTES:
44
+ return "walletSecret must be a base64-encoded EC P-256 private key (unexpected length)"
45
+ return True
46
+
47
+
48
+ def strip_wallet_auth_prefix(value: str) -> str:
49
+ trimmed = value.strip()
50
+ return trimmed[len(WALLET_AUTH_PREFIX) :] if trimmed.startswith(WALLET_AUTH_PREFIX) else trimmed
51
+
52
+
53
+ def validate_authorization_private_key(value: str) -> Literal[True] | str:
54
+ decoded = _decode_base64(strip_wallet_auth_prefix(value))
55
+ if decoded is None:
56
+ return "authorizationPrivateKey must be base64-encoded"
57
+ if not P256_MIN_BYTES <= len(decoded) <= P256_MAX_BYTES:
58
+ return "authorizationPrivateKey must be a base64-encoded EC P-256 private key (unexpected length)"
59
+ return True
60
+
61
+
62
+ __all__ = [
63
+ "WALLET_AUTH_PREFIX",
64
+ "strip_wallet_auth_prefix",
65
+ "validate_api_key_secret",
66
+ "validate_authorization_private_key",
67
+ "validate_wallet_secret",
68
+ ]