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,351 @@
1
+ """GET /api/resources (port of handlers/resources.ts): the project resource graph + deployment status."""
2
+
3
+ from typing import Any
4
+ from urllib.parse import quote
5
+
6
+ from agentcore.aws.partition import service_endpoint
7
+ from agentcore.lib.schemas.io.config_io import ConfigIO
8
+ from agentcore.operations.dev._server import Response
9
+ from agentcore.operations.dev.web_ui.handlers._common import send_json
10
+
11
+
12
+ def build_runtime_invocation_url(region: str, runtime_arn: str) -> str:
13
+ """Port of commands/status/constants.ts buildRuntimeInvocationUrl (encodeURIComponent)."""
14
+ encoded = quote(runtime_arn, safe="-_.!~*'()")
15
+ return f"https://{service_endpoint('bedrock-agentcore', region)}/runtimes/{encoded}/invocations"
16
+
17
+
18
+ def _compute_resource_statuses(project: Any, resources: Any) -> list[Any]:
19
+ """Delegates to the status command's computeResourceStatuses (owned by the deploy/status port)."""
20
+ try:
21
+ from agentcore.cli.commands.status.action import compute_resource_statuses
22
+ except ImportError:
23
+ try:
24
+ from agentcore.cli.commands.status import compute_resource_statuses # type: ignore[no-redef]
25
+ except ImportError:
26
+ return []
27
+ # The status port takes the deployed-state resources as camelCase JSON.
28
+ as_json = resources.to_json_dict() if hasattr(resources, "to_json_dict") else resources
29
+ return list(compute_resource_statuses(project, as_json))
30
+
31
+
32
+ def _entry(entry: Any, key: str) -> Any:
33
+ if isinstance(entry, dict):
34
+ return entry.get(key)
35
+ snake = "".join(f"_{c.lower()}" if c.isupper() else c for c in key)
36
+ return getattr(entry, snake, getattr(entry, key, None))
37
+
38
+
39
+ def _dump(model: Any) -> Any:
40
+ if model is None:
41
+ return None
42
+ return model.to_json_dict() if hasattr(model, "to_json_dict") else model
43
+
44
+
45
+ def _get(mapping: Any, name: str) -> Any:
46
+ return (mapping or {}).get(name)
47
+
48
+
49
+ def handle_resources(ctx: Any, res: Response, origin: str | None = None) -> None:
50
+ config_root = ctx.options.config_root
51
+ if not config_root:
52
+ send_json(ctx, res, origin, 404, {"success": False, "error": "No agentcore project found"})
53
+ return
54
+ try:
55
+ send_json(ctx, res, origin, 200, _build(ctx, config_root))
56
+ except Exception as err: # noqa: BLE001
57
+ ctx.log("error", f"Failed to read resources: {err}")
58
+ send_json(ctx, res, origin, 500, {"success": False, "error": "Failed to read project configuration"})
59
+
60
+
61
+ def _build(ctx: Any, config_root: str) -> dict[str, Any]:
62
+ config_io = ConfigIO(base_dir=config_root)
63
+ project = config_io.read_project_spec()
64
+
65
+ targets: dict[str, Any] = {}
66
+ if config_io.config_exists("state"):
67
+ try:
68
+ targets = dict(config_io.read_deployed_state().targets or {})
69
+ except Exception: # noqa: BLE001
70
+ ctx.log("warn", "Failed to read deployed state")
71
+ first_key = next(iter(targets), None)
72
+ tr = targets[first_key].resources if first_key and targets[first_key] else None
73
+
74
+ target_region: str | None = None
75
+ deployment_targets: list[dict[str, Any]] = []
76
+ try:
77
+ aws_targets = config_io.read_aws_deployment_targets()
78
+ first = next((t for t in aws_targets if t.name == first_key), None) if first_key else (aws_targets or [None])[0]
79
+ target_region = first.region if first else None
80
+ deployment_targets = [
81
+ {"name": t.name, "region": t.region, **({"description": t.description} if t.description else {})}
82
+ for t in aws_targets
83
+ ]
84
+ except Exception: # noqa: BLE001 - aws-targets.json may not exist yet
85
+ pass
86
+
87
+ status_by: dict[str, Any] = {}
88
+ for entry in _compute_resource_statuses(project, tr):
89
+ status_by[f"{_entry(entry, 'resourceType')}:{_entry(entry, 'name')}"] = _entry(entry, "deploymentState")
90
+
91
+ def inv_url(deployed: Any) -> str | None:
92
+ arn = getattr(deployed, "runtime_arn", None) if deployed else None
93
+ return build_runtime_invocation_url(target_region, arn) if arn and target_region else None
94
+
95
+ runtimes = (tr.runtimes if tr else None) or {}
96
+ agents = []
97
+ for a in project.runtimes:
98
+ deployed = runtimes.get(a.name)
99
+ agents.append(
100
+ {
101
+ "name": a.name,
102
+ "build": a.build,
103
+ "entrypoint": a.entrypoint,
104
+ "codeLocation": a.code_location,
105
+ "runtimeVersion": a.runtime_version or "",
106
+ "networkMode": a.network_mode or "PUBLIC",
107
+ "protocol": a.protocol or "HTTP",
108
+ "envVars": [e.name for e in a.env_vars or []],
109
+ "deploymentStatus": status_by.get(f"agent:{a.name}"),
110
+ "deployed": _dump(deployed),
111
+ "invocationUrl": inv_url(deployed),
112
+ }
113
+ )
114
+ local = {a.name for a in project.runtimes}
115
+ for name, deployed in runtimes.items():
116
+ if name not in local:
117
+ agents.append(
118
+ {
119
+ "name": name,
120
+ "build": "",
121
+ "entrypoint": "",
122
+ "codeLocation": "",
123
+ "runtimeVersion": "",
124
+ "networkMode": "",
125
+ "protocol": "",
126
+ "envVars": [],
127
+ "deploymentStatus": "pending-removal",
128
+ "deployed": _dump(deployed),
129
+ "invocationUrl": inv_url(deployed),
130
+ }
131
+ )
132
+
133
+ deployed_harnesses = (tr.harnesses if tr else None) or {}
134
+ credentials_state = (tr.credentials if tr else None) or {}
135
+ harnesses = []
136
+ for h in project.harnesses or []:
137
+ model, model_config, tools, skills = "", None, [], None
138
+ try:
139
+ spec = config_io.read_harness_spec(h.name)
140
+ model = f"{spec.model.provider}/{spec.model.model_id}"
141
+ model_config = _dump(spec.model)
142
+ tools = [t.name for t in spec.tools]
143
+ if spec.skills:
144
+ skills = []
145
+ for s in spec.skills:
146
+ if getattr(s, "s3_uri", None):
147
+ skills.append({"s3": {"uri": s.s3_uri}})
148
+ elif getattr(s, "git_url", None):
149
+ git: dict[str, Any] = {"url": s.git_url}
150
+ if s.path:
151
+ git["path"] = s.path
152
+ if s.auth:
153
+ cred = credentials_state.get(s.auth.credential_name)
154
+ git["auth"] = {
155
+ "credentialName": s.auth.credential_name,
156
+ "credentialArn": cred.credential_provider_arn if cred else None,
157
+ "username": s.auth.username,
158
+ }
159
+ skills.append({"git": git})
160
+ elif getattr(s, "aws_skills", None) is not None:
161
+ paths = s.aws_skills.paths
162
+ skills.append({"awsSkills": {"paths": paths} if paths else {}})
163
+ else:
164
+ skills.append({"path": s.path})
165
+ except Exception: # noqa: BLE001 - show what we can
166
+ pass
167
+ deployed = deployed_harnesses.get(h.name)
168
+ harnesses.append(
169
+ {
170
+ "name": h.name,
171
+ "model": model,
172
+ "modelConfig": model_config,
173
+ "tools": tools,
174
+ "skills": skills,
175
+ "deploymentStatus": status_by.get(f"harness:{h.name}"),
176
+ "deployed": {"harnessId": deployed.harness_id, "harnessArn": deployed.harness_arn}
177
+ if deployed
178
+ else None,
179
+ }
180
+ )
181
+ local = {h.name for h in project.harnesses or []}
182
+ for name, deployed in deployed_harnesses.items():
183
+ if name not in local:
184
+ harnesses.append(
185
+ {
186
+ "name": name,
187
+ "model": "",
188
+ "tools": [],
189
+ "deploymentStatus": "pending-removal",
190
+ "deployed": {"harnessId": deployed.harness_id, "harnessArn": deployed.harness_arn},
191
+ }
192
+ )
193
+
194
+ def pending(state_map: Any, local_names: set[str], make: Any) -> list[dict[str, Any]]:
195
+ return [make(n, d) for n, d in (state_map or {}).items() if n not in local_names]
196
+
197
+ mem_state = (tr.memories if tr else None) or {}
198
+ memories = [
199
+ {
200
+ "name": m.name,
201
+ "strategies": [
202
+ {
203
+ "type": s.type,
204
+ "namespaceTemplates": s.namespace_templates
205
+ if s.namespace_templates is not None
206
+ else (s.namespaces if s.namespaces is not None else []),
207
+ }
208
+ for s in m.strategies
209
+ ],
210
+ "expiryDays": m.event_expiry_duration,
211
+ "deploymentStatus": status_by.get(f"memory:{m.name}"),
212
+ "deployed": _dump(mem_state.get(m.name)),
213
+ }
214
+ for m in project.memories
215
+ ] + pending(
216
+ mem_state,
217
+ {m.name for m in project.memories},
218
+ lambda n, d: {"name": n, "strategies": [], "deploymentStatus": "pending-removal", "deployed": _dump(d)},
219
+ )
220
+
221
+ cred_state = credentials_state
222
+ credentials = [
223
+ {
224
+ "name": c.name,
225
+ "type": c.authorizer_type,
226
+ "deploymentStatus": status_by.get(f"credential:{c.name}"),
227
+ "deployed": _dump(cred_state.get(c.name)),
228
+ }
229
+ for c in project.credentials
230
+ ] + pending(
231
+ cred_state,
232
+ {c.name for c in project.credentials},
233
+ lambda n, d: {"name": n, "type": "", "deploymentStatus": "pending-removal", "deployed": _dump(d)},
234
+ )
235
+
236
+ mcp = tr.mcp if tr else None
237
+ gw_state = (mcp.gateways if mcp else None) or {}
238
+ gateways = [
239
+ {
240
+ "name": g.name,
241
+ "targets": [
242
+ {
243
+ "name": t.tool_definitions[0].name if t.tool_definitions else t.name,
244
+ "targetType": t.target_type,
245
+ }
246
+ for t in g.targets
247
+ ],
248
+ "deploymentStatus": status_by.get(f"gateway:{g.name}"),
249
+ "deployed": _dump(gw_state.get(g.name)),
250
+ }
251
+ for g in project.agent_core_gateways or []
252
+ ] + pending(
253
+ gw_state,
254
+ {g.name for g in project.agent_core_gateways or []},
255
+ lambda n, d: {"name": n, "targets": [], "deploymentStatus": "pending-removal", "deployed": _dump(d)},
256
+ )
257
+
258
+ mcp_runtime_tools = [
259
+ {"name": t.name, "bindings": [_dump(b) for b in t.bindings or []]} for t in project.mcp_runtime_tools or []
260
+ ]
261
+
262
+ ev_state = (tr.evaluators if tr else None) or {}
263
+ evaluators = [
264
+ {
265
+ "name": e.name,
266
+ "level": e.level,
267
+ "description": e.description,
268
+ "configType": "code-based" if e.config.code_based else "llm-as-a-judge",
269
+ "deploymentStatus": status_by.get(f"evaluator:{e.name}"),
270
+ "deployed": _dump(ev_state.get(e.name)),
271
+ }
272
+ for e in project.evaluators
273
+ ] + pending(
274
+ ev_state,
275
+ {e.name for e in project.evaluators},
276
+ lambda n, d: {
277
+ "name": n,
278
+ "level": "",
279
+ "configType": "llm-as-a-judge",
280
+ "deploymentStatus": "pending-removal",
281
+ "deployed": _dump(d),
282
+ },
283
+ )
284
+
285
+ oe_state = (tr.online_eval_configs if tr else None) or {}
286
+ online_eval_configs = [
287
+ {
288
+ "name": o.name,
289
+ "agent": o.agent,
290
+ "evaluators": o.evaluators,
291
+ "samplingRate": o.sampling_rate,
292
+ "description": o.description,
293
+ "deploymentStatus": status_by.get(f"online-eval:{o.name}"),
294
+ "deployed": _dump(oe_state.get(o.name)),
295
+ }
296
+ for o in project.online_eval_configs
297
+ ] + pending(
298
+ oe_state,
299
+ {o.name for o in project.online_eval_configs},
300
+ lambda n, d: {
301
+ "name": n,
302
+ "agent": "",
303
+ "evaluators": [],
304
+ "samplingRate": 0,
305
+ "deploymentStatus": "pending-removal",
306
+ "deployed": _dump(d),
307
+ },
308
+ )
309
+
310
+ pe_state = (tr.policy_engines if tr else None) or {}
311
+ pol_state = (tr.policies if tr else None) or {}
312
+ policy_engines = [
313
+ {
314
+ "name": pe.name,
315
+ "description": pe.description,
316
+ "policies": [
317
+ {
318
+ "name": p.name,
319
+ "description": p.description,
320
+ "deploymentStatus": status_by.get(f"policy:{pe.name}/{p.name}"),
321
+ "deployed": _dump(pol_state.get(f"{pe.name}/{p.name}") or pol_state.get(p.name)),
322
+ }
323
+ for p in pe.policies
324
+ ],
325
+ "deploymentStatus": status_by.get(f"policy-engine:{pe.name}"),
326
+ "deployed": _dump(pe_state.get(pe.name)),
327
+ }
328
+ for pe in project.policy_engines
329
+ ] + pending(
330
+ pe_state,
331
+ {pe.name for pe in project.policy_engines},
332
+ lambda n, d: {"name": n, "policies": [], "deploymentStatus": "pending-removal", "deployed": _dump(d)},
333
+ )
334
+
335
+ unassigned = [{"name": t.name, "targetType": t.target_type} for t in project.unassigned_targets or []]
336
+
337
+ return {
338
+ "success": True,
339
+ "project": project.name,
340
+ "agents": agents,
341
+ "harnesses": harnesses,
342
+ "memories": memories,
343
+ "credentials": credentials,
344
+ "gateways": gateways,
345
+ "mcpRuntimeTools": mcp_runtime_tools,
346
+ "evaluators": evaluators,
347
+ "onlineEvalConfigs": online_eval_configs,
348
+ "policyEngines": policy_engines,
349
+ "unassignedTargets": unassigned,
350
+ "deploymentTargets": deployment_targets,
351
+ }
@@ -0,0 +1,182 @@
1
+ """POST /api/start (port of handlers/start.ts): start an agent server on demand."""
2
+
3
+ import json
4
+ import time
5
+ from concurrent.futures import Future
6
+ from typing import Any
7
+
8
+ from agentcore.operations.dev._server import Request, Response
9
+ from agentcore.operations.dev.config import requires_exact_dev_port
10
+ from agentcore.operations.dev.constants import A2A_DEFAULT_PORT, MCP_DEFAULT_PORT
11
+ from agentcore.operations.dev.dev_server import DevServerCallbacks, DevServerOptions
12
+ from agentcore.operations.dev.server import create_dev_server
13
+ from agentcore.operations.dev.utils import find_available_port, wait_for_server_ready
14
+ from agentcore.operations.dev.web_ui.constants import AgentError
15
+ from agentcore.operations.dev.web_ui.handlers._common import send_json
16
+
17
+
18
+ def _now_ms() -> int:
19
+ return int(time.time() * 1000)
20
+
21
+
22
+ def handle_start(ctx: Any, req: Request, res: Response, origin: str | None = None) -> None:
23
+ body = ctx.read_body(req)
24
+ agent_name = None
25
+ try:
26
+ parsed = json.loads(body)
27
+ agent_name = parsed.get("agentName") if isinstance(parsed, dict) else None
28
+ except ValueError:
29
+ pass
30
+ if not agent_name:
31
+ send_json(ctx, res, origin, 400, {"success": False, "error": "agentName is required"})
32
+ return
33
+
34
+ if ctx.options.on_start:
35
+ result = ctx.options.on_start(agent_name)
36
+ send_json(ctx, res, origin, 200 if result.get("success") else 404, result)
37
+ return
38
+
39
+ with ctx.state_lock:
40
+ existing = ctx.running_agents.get(agent_name)
41
+ inflight = ctx.starting_agents.get(agent_name)
42
+ owner = False
43
+ if not existing and not inflight:
44
+ inflight = Future()
45
+ ctx.starting_agents[agent_name] = inflight
46
+ owner = True
47
+
48
+ if existing:
49
+ send_json(ctx, res, origin, 200, {"success": True, "name": agent_name, "port": existing.port})
50
+ return
51
+
52
+ assert inflight is not None
53
+ if not owner: # a start is already in flight: wait for it instead of spawning a duplicate
54
+ result = inflight.result()
55
+ send_json(ctx, res, origin, 200 if result.get("success") else 500, result)
56
+ return
57
+
58
+ try:
59
+ try:
60
+ result = do_start_agent(ctx, agent_name)
61
+ except BaseException as err:
62
+ inflight.set_exception(err)
63
+ raise
64
+ inflight.set_result(result)
65
+ send_json(ctx, res, origin, 200 if result.get("success") else 500, result)
66
+ finally:
67
+ with ctx.state_lock:
68
+ ctx.starting_agents.pop(agent_name, None)
69
+
70
+
71
+ def resolve_agent_target_port(
72
+ *,
73
+ protocol: str,
74
+ agent_name: str,
75
+ agent_index: int,
76
+ ui_port: int,
77
+ agent_base_port: int | None = None,
78
+ selected_agent: str | None = None,
79
+ ) -> int:
80
+ """MCP: 8000. Explicit -p for the selected runtime: literal. A2A: 9000+index. Else uiPort+1+index."""
81
+ safe_index = max(agent_index, 0)
82
+ if protocol == "MCP":
83
+ return MCP_DEFAULT_PORT
84
+ if agent_base_port is not None and agent_name == selected_agent:
85
+ return agent_base_port
86
+ if protocol == "A2A":
87
+ return A2A_DEFAULT_PORT + safe_index
88
+ return ui_port + 1 + safe_index
89
+
90
+
91
+ def do_start_agent(ctx: Any, agent_name: str) -> dict[str, Any]:
92
+ opts = ctx.options
93
+ if not opts.get_dev_config:
94
+ return {"success": False, "name": agent_name, "port": 0, "error": "Dev config factory not provided"}
95
+ config = opts.get_dev_config(agent_name)
96
+ if not config:
97
+ return {
98
+ "success": False,
99
+ "name": agent_name,
100
+ "port": 0,
101
+ "error": f'Agent "{agent_name}" not found or not supported',
102
+ }
103
+
104
+ filtered_index = next((i for i, a in enumerate(opts.agents) if a.get("name") == agent_name), -1)
105
+ agent_index = filtered_index
106
+ if filtered_index >= 0 and opts.agents[filtered_index].get("runtimeIndex") is not None:
107
+ agent_index = opts.agents[filtered_index]["runtimeIndex"]
108
+
109
+ is_a2a = config.protocol == "A2A"
110
+ is_ts_http = not config.is_python and config.protocol == "HTTP"
111
+ target_port = resolve_agent_target_port(
112
+ protocol=config.protocol,
113
+ agent_name=agent_name,
114
+ agent_index=agent_index,
115
+ ui_port=opts.ui_port,
116
+ agent_base_port=opts.agent_base_port,
117
+ selected_agent=opts.selected_agent,
118
+ )
119
+ port_is_explicit = opts.agent_base_port is not None and agent_name == opts.selected_agent
120
+ agent_port = find_available_port(target_port)
121
+ if requires_exact_dev_port(config.protocol) and agent_port != target_port:
122
+ error = (
123
+ f"Port {target_port} is in use. MCP agents require port {target_port} (FastMCP default)."
124
+ if config.protocol == "MCP"
125
+ else f"Port {target_port} is in use. A2A agents require port {target_port}."
126
+ )
127
+ return {"success": False, "name": agent_name, "port": 0, "error": error}
128
+ if port_is_explicit and agent_port != target_port:
129
+ return {
130
+ "success": False,
131
+ "name": agent_name,
132
+ "port": 0,
133
+ "error": f"Port {target_port} is in use. Free it or pass a different --port "
134
+ "(no port is chosen automatically when --port is set explicitly).",
135
+ }
136
+ if agent_port != target_port:
137
+ ctx.log("info", f"[{agent_name}] Port {target_port} in use, using {agent_port}")
138
+
139
+ error_messages: list[str] = []
140
+
141
+ def on_log(level: str, msg: str) -> None:
142
+ if level == "error":
143
+ error_messages.append(msg)
144
+ if agent_name in ctx.running_agents:
145
+ ctx.agent_errors[agent_name] = AgentError(msg, _now_ms())
146
+ ctx.log("error" if level == "error" else "info", f"[{agent_name}] {msg}")
147
+
148
+ def on_exit(code: int | None) -> None:
149
+ ctx.log("info", f"[{agent_name}] Server exited with code {code if code is not None else 0}")
150
+ ctx.running_agents.pop(agent_name, None)
151
+ if code not in (0, None):
152
+ message = "\n".join(error_messages) if error_messages else f"Server exited with code {code}"
153
+ ctx.agent_errors[agent_name] = AgentError(message, _now_ms())
154
+
155
+ base_env = opts.get_env_vars() if opts.get_env_vars else (opts.env_vars or {})
156
+ agent_env = {
157
+ **base_env,
158
+ "OTEL_SERVICE_NAME": agent_name,
159
+ **({"AGENTCORE_RUNTIME_URL": f"http://localhost:{agent_port}/"} if is_a2a else {}),
160
+ **({"PORT": str(agent_port)} if is_ts_http else {}),
161
+ }
162
+ server = create_dev_server(
163
+ config, DevServerOptions(port=agent_port, env_vars=agent_env, callbacks=DevServerCallbacks(on_log, on_exit))
164
+ )
165
+ ctx.agent_errors.pop(agent_name, None)
166
+ child = server.start()
167
+ if child is None:
168
+ message = "\n".join(error_messages) if error_messages else "Agent server failed to start"
169
+ ctx.agent_errors[agent_name] = AgentError(message, _now_ms())
170
+ return {"success": False, "name": agent_name, "port": 0, "error": message}
171
+
172
+ if not wait_for_server_ready(agent_port):
173
+ message = (
174
+ "\n".join(error_messages) if error_messages else "Agent server started but is not accepting connections"
175
+ )
176
+ ctx.agent_errors[agent_name] = AgentError(message, _now_ms())
177
+ return {"success": False, "name": agent_name, "port": 0, "error": message}
178
+
179
+ from agentcore.operations.dev.web_ui.web_server import RunningAgent
180
+
181
+ ctx.running_agents[agent_name] = RunningAgent(server=server, port=agent_port, protocol=config.protocol)
182
+ return {"success": True, "name": agent_name, "port": agent_port}
@@ -0,0 +1,25 @@
1
+ """GET /api/status (port of handlers/status.ts)."""
2
+
3
+ from typing import Any
4
+
5
+ from agentcore.operations.dev._server import Response
6
+ from agentcore.operations.dev.web_ui.handlers._common import send_json
7
+
8
+
9
+ def handle_status(ctx: Any, res: Response, origin: str | None = None) -> None:
10
+ opts = ctx.options
11
+ send_json(
12
+ ctx,
13
+ res,
14
+ origin,
15
+ 200,
16
+ {
17
+ "mode": opts.mode,
18
+ "agents": opts.agents,
19
+ "harnesses": [{"name": h.name} for h in opts.harnesses or []],
20
+ "running": [{"name": name, "port": a.port} for name, a in list(ctx.running_agents.items())],
21
+ "errors": [{"name": name, "message": e.message} for name, e in list(ctx.agent_errors.items())],
22
+ "selectedAgent": opts.selected_agent,
23
+ "selectedHarness": opts.selected_harness,
24
+ },
25
+ )
@@ -0,0 +1,50 @@
1
+ """GET /api/traces and /api/traces/:traceId (port of handlers/traces.ts)."""
2
+
3
+ from typing import Any
4
+
5
+ from agentcore.operations.dev._server import Request, Response
6
+ from agentcore.operations.dev.web_ui.handlers._common import parse_time_params, send_json
7
+
8
+
9
+ def handle_list_traces(ctx: Any, req: Request, res: Response, origin: str | None = None) -> None:
10
+ from agentcore.operations.dev.web_ui.web_server import parse_request_url
11
+
12
+ _, param = parse_request_url(req)
13
+ handler = ctx.options.on_list_traces
14
+ if not handler:
15
+ send_json(ctx, res, origin, 404, {"success": False, "error": "Traces are not available"})
16
+ return
17
+ agent_name = param("agentName")
18
+ ok, start, end = parse_time_params(ctx, res, origin, param)
19
+ if not ok:
20
+ return
21
+ try:
22
+ result = handler(agent_name, start, end)
23
+ send_json(ctx, res, origin, 200 if result.get("success") else 500, result)
24
+ except Exception as err: # noqa: BLE001
25
+ ctx.log("error", f"List traces error: {err}")
26
+ send_json(ctx, res, origin, 500, {"success": False, "error": "Failed to list traces"})
27
+
28
+
29
+ def handle_get_trace(ctx: Any, req: Request, res: Response, origin: str | None = None) -> None:
30
+ from agentcore.operations.dev.web_ui.web_server import parse_request_url
31
+
32
+ pathname, param = parse_request_url(req)
33
+ handler = ctx.options.on_get_trace
34
+ if not handler:
35
+ send_json(ctx, res, origin, 404, {"success": False, "error": "Traces are not available"})
36
+ return
37
+ trace_id = pathname.replace("/api/traces/", "", 1)
38
+ agent_name = param("agentName")
39
+ if not trace_id:
40
+ send_json(ctx, res, origin, 400, {"success": False, "error": "traceId is required in the URL path"})
41
+ return
42
+ ok, start, end = parse_time_params(ctx, res, origin, param)
43
+ if not ok:
44
+ return
45
+ try:
46
+ result = handler(agent_name, trace_id, start, end)
47
+ send_json(ctx, res, origin, 200 if result.get("success") else 500, result)
48
+ except Exception as err: # noqa: BLE001
49
+ ctx.log("error", f"Get trace error: {err}")
50
+ send_json(ctx, res, origin, 500, {"success": False, "error": "Failed to get trace"})
@@ -0,0 +1,60 @@
1
+ """Port of operations/dev/web-ui/run-web-ui.ts: launch the web UI and block until Ctrl+C."""
2
+
3
+ import threading
4
+ from collections.abc import Callable
5
+ from typing import Any
6
+
7
+ from agentcore.logging import ExecLogger
8
+ from agentcore.operations.dev.utils import find_available_port, on_shutdown_signal, open_browser
9
+ from agentcore.operations.dev.web_ui.constants import WEB_UI_DEFAULT_PORT
10
+ from agentcore.operations.dev.web_ui.web_server import WebUIOptions, WebUIServer
11
+
12
+
13
+ def run_web_ui(
14
+ server_options: dict[str, Any],
15
+ log_label: str,
16
+ on_log: Callable[[str, str], None] | None = None,
17
+ ) -> None:
18
+ """``server_options`` are WebUIOptions fields minus ui_port/on_ready/on_log."""
19
+ import sys
20
+
21
+ logger = ExecLogger(command=log_label)
22
+ ui_port = find_available_port(WEB_UI_DEFAULT_PORT)
23
+ if ui_port != WEB_UI_DEFAULT_PORT:
24
+ print(f"Port {WEB_UI_DEFAULT_PORT} in use, using {ui_port}")
25
+ print("Starting web UI...")
26
+ print(f"Log: {logger.get_relative_log_path()}")
27
+
28
+ def default_display(level: str, msg: str) -> None:
29
+ if level == "error":
30
+ print(f"Web UI: {msg}", file=sys.stderr)
31
+
32
+ display = on_log or default_display
33
+
34
+ def log(level: str, msg: str) -> None:
35
+ logger.log(msg, level) # type: ignore[arg-type]
36
+ display(level, msg)
37
+
38
+ def on_ready(url: str) -> None:
39
+ print(f"\nChat UI: {url}")
40
+ print("Press Ctrl+C to stop\n", flush=True)
41
+ open_browser(url)
42
+
43
+ web_ui = WebUIServer(WebUIOptions(**server_options, ui_port=ui_port, on_ready=on_ready, on_log=log))
44
+ web_ui.start()
45
+
46
+ stopped = threading.Event()
47
+
48
+ def shutdown() -> None:
49
+ print("\nStopping servers...")
50
+ web_ui.stop()
51
+ logger.finalize(True)
52
+ stopped.set()
53
+
54
+ on_shutdown_signal(shutdown)
55
+ try:
56
+ while not stopped.wait(0.5):
57
+ pass
58
+ except KeyboardInterrupt:
59
+ if not stopped.is_set():
60
+ shutdown()