@aws/agentcore 1.0.0-preview.3 → 1.0.0-preview.31

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 (330) hide show
  1. package/README.md +193 -33
  2. package/dist/agent-inspector/index.css +1 -1
  3. package/dist/agent-inspector/index.js +99 -84
  4. package/dist/assets/README.md +6 -2
  5. package/dist/assets/__tests__/__snapshots__/assets.snapshot.test.ts.snap +3344 -366
  6. package/dist/assets/__tests__/__snapshots__/dockerfile-render.test.ts.snap +6 -2
  7. package/dist/assets/__tests__/assets.snapshot.test.ts +10 -24
  8. package/dist/assets/__tests__/googleadk-observability.test.ts +23 -0
  9. package/dist/assets/__tests__/googleadk-session-eviction.test.ts +87 -0
  10. package/dist/assets/__tests__/input-validation.test.ts +44 -0
  11. package/dist/assets/__tests__/summarization-namespace.test.ts +43 -0
  12. package/dist/assets/agents/AGENTS.md +91 -14
  13. package/dist/assets/cdk/bin/cdk.ts +109 -24
  14. package/dist/assets/cdk/lib/cdk-stack.ts +227 -19
  15. package/dist/assets/cdk/package.json +9 -9
  16. package/dist/assets/cdk/test/cdk.test.ts +4 -0
  17. package/dist/assets/container/python/Dockerfile +7 -1
  18. package/dist/assets/container/typescript/Dockerfile +25 -0
  19. package/dist/assets/container/typescript/dockerignore.template +24 -0
  20. package/dist/assets/datasets/predefined-v1.jsonl +3 -0
  21. package/dist/assets/datasets/simulated-v1.jsonl +3 -0
  22. package/dist/assets/evaluators/autoevals-lambda/execution-role-policy.json +15 -0
  23. package/dist/assets/evaluators/autoevals-lambda/lambda_function.py +37 -0
  24. package/dist/assets/evaluators/autoevals-lambda/pyproject.toml +22 -0
  25. package/dist/assets/evaluators/deepeval-lambda/execution-role-policy.json +15 -0
  26. package/dist/assets/evaluators/deepeval-lambda/lambda_function.py +29 -0
  27. package/dist/assets/evaluators/deepeval-lambda/pyproject.toml +19 -0
  28. package/dist/assets/mcp/python/pyproject.toml +1 -1
  29. package/dist/assets/python/a2a/googleadk/base/main.py +32 -18
  30. package/dist/assets/python/a2a/googleadk/base/pyproject.toml +6 -4
  31. package/dist/assets/python/a2a/langchain_langgraph/base/main.py +35 -21
  32. package/dist/assets/python/a2a/langchain_langgraph/base/pyproject.toml +4 -3
  33. package/dist/assets/python/a2a/strands/base/main.py +23 -17
  34. package/dist/assets/python/a2a/strands/base/pyproject.toml +3 -3
  35. package/dist/assets/python/a2a/strands/capabilities/memory/session.py +4 -1
  36. package/dist/assets/python/agui/googleadk/base/main.py +62 -2
  37. package/dist/assets/python/agui/googleadk/base/pyproject.toml +6 -5
  38. package/dist/assets/python/agui/langchain_langgraph/base/main.py +56 -0
  39. package/dist/assets/python/agui/langchain_langgraph/base/pyproject.toml +3 -2
  40. package/dist/assets/python/agui/strands/base/main.py +63 -1
  41. package/dist/assets/python/agui/strands/base/pyproject.toml +2 -2
  42. package/dist/assets/python/agui/strands/capabilities/memory/session.py +4 -1
  43. package/dist/assets/python/http/autogen/base/README.md +7 -1
  44. package/dist/assets/python/http/autogen/base/main.py +62 -29
  45. package/dist/assets/python/http/autogen/base/pyproject.toml +1 -1
  46. package/dist/assets/python/http/googleadk/base/README.md +7 -1
  47. package/dist/assets/python/http/googleadk/base/main.py +71 -24
  48. package/dist/assets/python/http/googleadk/base/mcp_client/client.py +7 -7
  49. package/dist/assets/python/http/googleadk/base/pyproject.toml +5 -3
  50. package/dist/assets/python/http/langchain_langgraph/base/README.md +7 -1
  51. package/dist/assets/python/http/langchain_langgraph/base/main.py +119 -24
  52. package/dist/assets/python/http/langchain_langgraph/base/mcp_client/client.py +10 -8
  53. package/dist/assets/python/http/langchain_langgraph/base/pyproject.toml +5 -4
  54. package/dist/assets/python/http/openaiagents/base/README.md +7 -1
  55. package/dist/assets/python/http/openaiagents/base/main.py +63 -32
  56. package/dist/assets/python/http/openaiagents/base/mcp_client/client.py +4 -4
  57. package/dist/assets/python/http/openaiagents/base/pyproject.toml +3 -3
  58. package/dist/assets/python/http/strands/base/README.md +8 -1
  59. package/dist/assets/python/http/strands/base/main.py +607 -47
  60. package/dist/assets/python/http/strands/base/mcp_client/client.py +49 -6
  61. package/dist/assets/python/http/strands/base/model/load.py +119 -3
  62. package/dist/assets/python/http/strands/base/model/mantle_compat.py +21 -0
  63. package/dist/assets/python/http/strands/base/pyproject.toml +11 -5
  64. package/dist/assets/python/http/strands/base/skills/fetcher.py +279 -0
  65. package/dist/assets/python/http/strands/capabilities/execution-limits/hooks/execution_limits.py +54 -0
  66. package/dist/assets/python/http/strands/capabilities/memory/session.py +4 -1
  67. package/dist/assets/python/http/strands/capabilities/payments/__init__.py +4 -0
  68. package/dist/assets/python/http/strands/capabilities/payments/payments.py +142 -0
  69. package/dist/assets/python/mcp/standalone/base/main.py +58 -0
  70. package/dist/assets/python/mcp/standalone/base/pyproject.toml +1 -1
  71. package/dist/assets/typescript/http/strands/base/README.md +42 -0
  72. package/dist/assets/typescript/http/strands/base/gitignore.template +22 -0
  73. package/dist/assets/typescript/http/strands/base/main.ts +149 -0
  74. package/dist/assets/typescript/http/strands/base/mcp_client/client.ts +11 -0
  75. package/dist/assets/typescript/http/strands/base/model/load.ts +102 -0
  76. package/dist/assets/typescript/http/strands/base/package.json +38 -0
  77. package/dist/assets/typescript/http/strands/base/tsconfig.json +19 -0
  78. package/dist/assets/typescript/http/strands/capabilities/memory/memory.ts +52 -0
  79. package/dist/assets/typescript/http/vercelai/base/README.md +42 -0
  80. package/dist/assets/typescript/http/vercelai/base/gitignore.template +22 -0
  81. package/dist/assets/typescript/http/vercelai/base/main.ts +70 -0
  82. package/dist/assets/typescript/http/vercelai/base/model/load.ts +121 -0
  83. package/dist/assets/typescript/http/vercelai/base/package.json +35 -0
  84. package/dist/assets/typescript/http/vercelai/base/tsconfig.json +19 -0
  85. package/dist/cli/index.mjs +1743 -627
  86. package/dist/lib/constants.d.ts +8 -4
  87. package/dist/lib/constants.d.ts.map +1 -1
  88. package/dist/lib/constants.js +13 -7
  89. package/dist/lib/constants.js.map +1 -1
  90. package/dist/lib/dependency-management/index.d.ts +5 -0
  91. package/dist/lib/dependency-management/index.d.ts.map +1 -0
  92. package/dist/lib/dependency-management/index.js +8 -0
  93. package/dist/lib/dependency-management/index.js.map +1 -0
  94. package/dist/lib/dependency-management/messages.d.ts +30 -0
  95. package/dist/lib/dependency-management/messages.d.ts.map +1 -0
  96. package/dist/lib/dependency-management/messages.js +86 -0
  97. package/dist/lib/dependency-management/messages.js.map +1 -0
  98. package/dist/lib/dependency-management/plan.d.ts +25 -0
  99. package/dist/lib/dependency-management/plan.d.ts.map +1 -0
  100. package/dist/lib/dependency-management/plan.js +67 -0
  101. package/dist/lib/dependency-management/plan.js.map +1 -0
  102. package/dist/lib/dependency-management/semver.d.ts +21 -0
  103. package/dist/lib/dependency-management/semver.d.ts.map +1 -0
  104. package/dist/lib/dependency-management/semver.js +51 -0
  105. package/dist/lib/dependency-management/semver.js.map +1 -0
  106. package/dist/lib/dependency-management/sync.d.ts +26 -0
  107. package/dist/lib/dependency-management/sync.d.ts.map +1 -0
  108. package/dist/lib/dependency-management/sync.js +141 -0
  109. package/dist/lib/dependency-management/sync.js.map +1 -0
  110. package/dist/lib/dependency-management/types.d.ts +85 -0
  111. package/dist/lib/dependency-management/types.d.ts.map +1 -0
  112. package/dist/lib/dependency-management/types.js +3 -0
  113. package/dist/lib/dependency-management/types.js.map +1 -0
  114. package/dist/lib/errors/index.d.ts +1 -1
  115. package/dist/lib/errors/index.d.ts.map +1 -1
  116. package/dist/lib/errors/index.js +1 -1
  117. package/dist/lib/errors/index.js.map +1 -1
  118. package/dist/lib/errors/types.d.ts +274 -0
  119. package/dist/lib/errors/types.d.ts.map +1 -0
  120. package/dist/lib/errors/types.js +423 -0
  121. package/dist/lib/errors/types.js.map +1 -0
  122. package/dist/lib/errors/zod.d.ts +8 -0
  123. package/dist/lib/errors/zod.d.ts.map +1 -0
  124. package/dist/lib/errors/{config.js → zod.js} +8 -81
  125. package/dist/lib/errors/zod.js.map +1 -0
  126. package/dist/lib/index.d.ts +3 -0
  127. package/dist/lib/index.d.ts.map +1 -1
  128. package/dist/lib/index.js +4 -1
  129. package/dist/lib/index.js.map +1 -1
  130. package/dist/lib/packaging/build-args.d.ts +6 -0
  131. package/dist/lib/packaging/build-args.d.ts.map +1 -1
  132. package/dist/lib/packaging/build-args.js +11 -2
  133. package/dist/lib/packaging/build-args.js.map +1 -1
  134. package/dist/lib/packaging/build-context-dockerignore.d.ts +23 -0
  135. package/dist/lib/packaging/build-context-dockerignore.d.ts.map +1 -0
  136. package/dist/lib/packaging/build-context-dockerignore.js +63 -0
  137. package/dist/lib/packaging/build-context-dockerignore.js.map +1 -0
  138. package/dist/lib/packaging/build-context.d.ts +21 -0
  139. package/dist/lib/packaging/build-context.d.ts.map +1 -0
  140. package/dist/lib/packaging/build-context.js +21 -0
  141. package/dist/lib/packaging/build-context.js.map +1 -0
  142. package/dist/lib/packaging/container.d.ts.map +1 -1
  143. package/dist/lib/packaging/container.js +20 -9
  144. package/dist/lib/packaging/container.js.map +1 -1
  145. package/dist/lib/packaging/helpers.d.ts +16 -0
  146. package/dist/lib/packaging/helpers.d.ts.map +1 -1
  147. package/dist/lib/packaging/helpers.js +127 -29
  148. package/dist/lib/packaging/helpers.js.map +1 -1
  149. package/dist/lib/packaging/index.d.ts +2 -1
  150. package/dist/lib/packaging/index.d.ts.map +1 -1
  151. package/dist/lib/packaging/index.js +9 -20
  152. package/dist/lib/packaging/index.js.map +1 -1
  153. package/dist/lib/packaging/node.d.ts +2 -2
  154. package/dist/lib/packaging/node.d.ts.map +1 -1
  155. package/dist/lib/packaging/node.js +83 -38
  156. package/dist/lib/packaging/node.js.map +1 -1
  157. package/dist/lib/packaging/python.js +12 -12
  158. package/dist/lib/packaging/python.js.map +1 -1
  159. package/dist/lib/result.d.ts +57 -0
  160. package/dist/lib/result.d.ts.map +1 -0
  161. package/dist/lib/result.js +62 -0
  162. package/dist/lib/result.js.map +1 -0
  163. package/dist/lib/schemas/io/config-io.d.ts +14 -0
  164. package/dist/lib/schemas/io/config-io.d.ts.map +1 -1
  165. package/dist/lib/schemas/io/config-io.js +89 -5
  166. package/dist/lib/schemas/io/config-io.js.map +1 -1
  167. package/dist/lib/schemas/io/global-config.d.ts +41 -0
  168. package/dist/lib/schemas/io/global-config.d.ts.map +1 -0
  169. package/dist/lib/schemas/io/global-config.js +119 -0
  170. package/dist/lib/schemas/io/global-config.js.map +1 -0
  171. package/dist/lib/schemas/io/index.d.ts +1 -2
  172. package/dist/lib/schemas/io/index.d.ts.map +1 -1
  173. package/dist/lib/schemas/io/index.js +1 -4
  174. package/dist/lib/schemas/io/index.js.map +1 -1
  175. package/dist/lib/schemas/io/path-resolver.d.ts +0 -6
  176. package/dist/lib/schemas/io/path-resolver.d.ts.map +1 -1
  177. package/dist/lib/schemas/io/path-resolver.js +3 -13
  178. package/dist/lib/schemas/io/path-resolver.js.map +1 -1
  179. package/dist/lib/secrets/cipher.d.ts +12 -0
  180. package/dist/lib/secrets/cipher.d.ts.map +1 -0
  181. package/dist/lib/secrets/cipher.js +54 -0
  182. package/dist/lib/secrets/cipher.js.map +1 -0
  183. package/dist/lib/secrets/index.d.ts +4 -0
  184. package/dist/lib/secrets/index.d.ts.map +1 -0
  185. package/dist/lib/secrets/index.js +15 -0
  186. package/dist/lib/secrets/index.js.map +1 -0
  187. package/dist/lib/secrets/key-provider.d.ts +16 -0
  188. package/dist/lib/secrets/key-provider.d.ts.map +1 -0
  189. package/dist/lib/secrets/key-provider.js +191 -0
  190. package/dist/lib/secrets/key-provider.js.map +1 -0
  191. package/dist/lib/secrets/sensitive-keys.d.ts +21 -0
  192. package/dist/lib/secrets/sensitive-keys.d.ts.map +1 -0
  193. package/dist/lib/secrets/sensitive-keys.js +67 -0
  194. package/dist/lib/secrets/sensitive-keys.js.map +1 -0
  195. package/dist/lib/time-constants.d.ts +5 -0
  196. package/dist/lib/time-constants.d.ts.map +1 -0
  197. package/dist/lib/time-constants.js +8 -0
  198. package/dist/lib/time-constants.js.map +1 -0
  199. package/dist/lib/utils/env.d.ts +8 -2
  200. package/dist/lib/utils/env.d.ts.map +1 -1
  201. package/dist/lib/utils/env.js +65 -17
  202. package/dist/lib/utils/env.js.map +1 -1
  203. package/dist/lib/utils/index.d.ts +3 -2
  204. package/dist/lib/utils/index.d.ts.map +1 -1
  205. package/dist/lib/utils/index.js +6 -1
  206. package/dist/lib/utils/index.js.map +1 -1
  207. package/dist/lib/utils/polling.d.ts +31 -0
  208. package/dist/lib/utils/polling.d.ts.map +1 -0
  209. package/dist/lib/utils/polling.js +61 -0
  210. package/dist/lib/utils/polling.js.map +1 -0
  211. package/dist/lib/utils/subprocess.d.ts +4 -1
  212. package/dist/lib/utils/subprocess.d.ts.map +1 -1
  213. package/dist/lib/utils/subprocess.js +11 -57
  214. package/dist/lib/utils/subprocess.js.map +1 -1
  215. package/dist/lib/utils/zod.d.ts +16 -0
  216. package/dist/lib/utils/zod.d.ts.map +1 -1
  217. package/dist/lib/utils/zod.js +45 -0
  218. package/dist/lib/utils/zod.js.map +1 -1
  219. package/dist/schema/constants.d.ts +56 -2
  220. package/dist/schema/constants.d.ts.map +1 -1
  221. package/dist/schema/constants.js +82 -7
  222. package/dist/schema/constants.js.map +1 -1
  223. package/dist/schema/schemas/agent-env.d.ts +187 -7
  224. package/dist/schema/schemas/agent-env.d.ts.map +1 -1
  225. package/dist/schema/schemas/agent-env.js +323 -27
  226. package/dist/schema/schemas/agent-env.js.map +1 -1
  227. package/dist/schema/schemas/agentcore-project.d.ts +519 -12
  228. package/dist/schema/schemas/agentcore-project.d.ts.map +1 -1
  229. package/dist/schema/schemas/agentcore-project.js +342 -13
  230. package/dist/schema/schemas/agentcore-project.js.map +1 -1
  231. package/dist/schema/schemas/auth.d.ts +174 -0
  232. package/dist/schema/schemas/auth.d.ts.map +1 -1
  233. package/dist/schema/schemas/auth.js +127 -3
  234. package/dist/schema/schemas/auth.js.map +1 -1
  235. package/dist/schema/schemas/aws-targets.d.ts +18 -0
  236. package/dist/schema/schemas/aws-targets.d.ts.map +1 -1
  237. package/dist/schema/schemas/aws-targets.js +6 -0
  238. package/dist/schema/schemas/aws-targets.js.map +1 -1
  239. package/dist/schema/schemas/connections.d.ts +185 -0
  240. package/dist/schema/schemas/connections.d.ts.map +1 -0
  241. package/dist/schema/schemas/connections.js +176 -0
  242. package/dist/schema/schemas/connections.js.map +1 -0
  243. package/dist/schema/schemas/deployed-state.d.ts +392 -5
  244. package/dist/schema/schemas/deployed-state.d.ts.map +1 -1
  245. package/dist/schema/schemas/deployed-state.js +112 -2
  246. package/dist/schema/schemas/deployed-state.js.map +1 -1
  247. package/dist/schema/schemas/index.d.ts +3 -0
  248. package/dist/schema/schemas/index.d.ts.map +1 -1
  249. package/dist/schema/schemas/index.js +5 -0
  250. package/dist/schema/schemas/index.js.map +1 -1
  251. package/dist/schema/schemas/mcp-defs.d.ts +2 -1
  252. package/dist/schema/schemas/mcp-defs.d.ts.map +1 -1
  253. package/dist/schema/schemas/mcp-defs.js +3 -2
  254. package/dist/schema/schemas/mcp-defs.js.map +1 -1
  255. package/dist/schema/schemas/mcp.d.ts +197 -0
  256. package/dist/schema/schemas/mcp.d.ts.map +1 -1
  257. package/dist/schema/schemas/mcp.js +334 -5
  258. package/dist/schema/schemas/mcp.js.map +1 -1
  259. package/dist/schema/schemas/primitives/ab-test.d.ts +135 -0
  260. package/dist/schema/schemas/primitives/ab-test.d.ts.map +1 -0
  261. package/dist/schema/schemas/primitives/ab-test.js +95 -0
  262. package/dist/schema/schemas/primitives/ab-test.js.map +1 -0
  263. package/dist/schema/schemas/primitives/capacity-provider.d.ts +237 -0
  264. package/dist/schema/schemas/primitives/capacity-provider.d.ts.map +1 -0
  265. package/dist/schema/schemas/primitives/capacity-provider.js +220 -0
  266. package/dist/schema/schemas/primitives/capacity-provider.js.map +1 -0
  267. package/dist/schema/schemas/primitives/config-bundle.d.ts +32 -0
  268. package/dist/schema/schemas/primitives/config-bundle.d.ts.map +1 -0
  269. package/dist/schema/schemas/primitives/config-bundle.js +41 -0
  270. package/dist/schema/schemas/primitives/config-bundle.js.map +1 -0
  271. package/dist/schema/schemas/primitives/dataset.d.ts +48 -0
  272. package/dist/schema/schemas/primitives/dataset.d.ts.map +1 -0
  273. package/dist/schema/schemas/primitives/dataset.js +58 -0
  274. package/dist/schema/schemas/primitives/dataset.js.map +1 -0
  275. package/dist/schema/schemas/primitives/evaluator.d.ts +22 -0
  276. package/dist/schema/schemas/primitives/evaluator.d.ts.map +1 -1
  277. package/dist/schema/schemas/primitives/evaluator.js +28 -3
  278. package/dist/schema/schemas/primitives/evaluator.js.map +1 -1
  279. package/dist/schema/schemas/primitives/harness.d.ts +377 -19
  280. package/dist/schema/schemas/primitives/harness.d.ts.map +1 -1
  281. package/dist/schema/schemas/primitives/harness.js +379 -24
  282. package/dist/schema/schemas/primitives/harness.js.map +1 -1
  283. package/dist/schema/schemas/primitives/index.d.ts +17 -9
  284. package/dist/schema/schemas/primitives/index.d.ts.map +1 -1
  285. package/dist/schema/schemas/primitives/index.js +62 -1
  286. package/dist/schema/schemas/primitives/index.js.map +1 -1
  287. package/dist/schema/schemas/primitives/knowledge-base.d.ts +104 -0
  288. package/dist/schema/schemas/primitives/knowledge-base.d.ts.map +1 -0
  289. package/dist/schema/schemas/primitives/knowledge-base.js +99 -0
  290. package/dist/schema/schemas/primitives/knowledge-base.js.map +1 -0
  291. package/dist/schema/schemas/primitives/memory.d.ts +22 -4
  292. package/dist/schema/schemas/primitives/memory.d.ts.map +1 -1
  293. package/dist/schema/schemas/primitives/memory.js +57 -16
  294. package/dist/schema/schemas/primitives/memory.js.map +1 -1
  295. package/dist/schema/schemas/primitives/online-eval-config.d.ts +21 -2
  296. package/dist/schema/schemas/primitives/online-eval-config.d.ts.map +1 -1
  297. package/dist/schema/schemas/primitives/online-eval-config.js +45 -5
  298. package/dist/schema/schemas/primitives/online-eval-config.js.map +1 -1
  299. package/dist/schema/schemas/primitives/payment.d.ts +86 -0
  300. package/dist/schema/schemas/primitives/payment.d.ts.map +1 -0
  301. package/dist/schema/schemas/primitives/payment.js +88 -0
  302. package/dist/schema/schemas/primitives/payment.js.map +1 -0
  303. package/dist/schema/schemas/primitives/policy.d.ts +26 -0
  304. package/dist/schema/schemas/primitives/policy.d.ts.map +1 -1
  305. package/dist/schema/schemas/primitives/policy.js +5 -1
  306. package/dist/schema/schemas/primitives/policy.js.map +1 -1
  307. package/npm-shrinkwrap.json +16874 -0
  308. package/package.json +49 -21
  309. package/scripts/bump-version.ts +4 -4
  310. package/scripts/bundle.mjs +70 -41
  311. package/scripts/extract-cli-model.mjs +269 -0
  312. package/scripts/extract-cli-model.test.mjs +43 -0
  313. package/scripts/render_adoc.py +350 -0
  314. package/scripts/run-e2e-dev.sh +56 -0
  315. package/scripts/run-e2e-local.sh +145 -0
  316. package/scripts/safe-junit-reporter.ts +7 -0
  317. package/scripts/sanitize-test-artifacts.ts +65 -0
  318. package/scripts/sync-vended-cdk.ts +49 -0
  319. package/scripts/test_render_adoc.py +38 -0
  320. package/dist/lib/errors/config.d.ts +0 -49
  321. package/dist/lib/errors/config.d.ts.map +0 -1
  322. package/dist/lib/errors/config.js.map +0 -1
  323. package/dist/lib/packaging/errors.d.ts +0 -16
  324. package/dist/lib/packaging/errors.d.ts.map +0 -1
  325. package/dist/lib/packaging/errors.js +0 -36
  326. package/dist/lib/packaging/errors.js.map +0 -1
  327. package/dist/lib/schemas/io/cli-config.d.ts +0 -12
  328. package/dist/lib/schemas/io/cli-config.d.ts.map +0 -1
  329. package/dist/lib/schemas/io/cli-config.js +0 -35
  330. package/dist/lib/schemas/io/cli-config.js.map +0 -1
@@ -0,0 +1,43 @@
1
+ import { normalizeParameterDescription, parseHelp } from './extract-cli-model.mjs';
2
+ import assert from 'node:assert/strict';
3
+ import test from 'node:test';
4
+
5
+ test('parseHelp preserves wrapped argument and option descriptions', () => {
6
+ const parsed = parseHelp(`Usage: agentcore invoke [options] [prompt]
7
+
8
+ Invoke an agent.
9
+
10
+ Arguments:
11
+ prompt Prompt to send to the agent. Also accepts piped
12
+ stdin when no prompt is provided
13
+
14
+ Options:
15
+ --prompt-file <path> Read the prompt from a file (for long or
16
+ structured payloads that exceed shell limits)
17
+
18
+ Output
19
+ --json Output as JSON
20
+ `);
21
+
22
+ assert.equal(
23
+ parsed.args[0].description,
24
+ 'Prompt to send to the agent. Also accepts piped stdin when no prompt is provided'
25
+ );
26
+ assert.equal(
27
+ parsed.options[0].description,
28
+ 'Read the prompt from a file (for long or structured payloads that exceed shell limits)'
29
+ );
30
+ assert.equal(parsed.options[1].description, 'Output as JSON');
31
+ });
32
+
33
+ test('normalizeParameterDescription expands model provider and LiteLLM fragments', () => {
34
+ assert.equal(
35
+ normalizeParameterDescription('bedrock, open_ai, or gemini'),
36
+ 'The model provider. Valid values: `bedrock`, `open_ai`, or `gemini`.'
37
+ );
38
+ assert.equal(
39
+ normalizeParameterDescription('Override LiteLLM API base URL (harness only, lite_llm) [non-interactive]'),
40
+ 'The LiteLLM API base URL override for harness invocations. ' +
41
+ 'Available only with `lite_llm` in non-interactive mode.'
42
+ );
43
+ });
@@ -0,0 +1,350 @@
1
+ #!/usr/bin/env python3
2
+ # =============================================================================
3
+ # render_adoc.py — shared doc-model -> AsciiDoc renderer
4
+ # =============================================================================
5
+ # Renders a normalized "doc-model" JSON (produced by any of the three
6
+ # extractors) into .adoc files for the documentation repository.
7
+ #
8
+ # It is deliberately source-agnostic: the Python extractor, the TypeScript
9
+ # TypeDoc extractor, and the CLI --help extractor all emit the SAME doc-model
10
+ # schema, so this one renderer produces consistent output for all three.
11
+ #
12
+ # NOTE: if these workflows are later consolidated into a single shared reusable
13
+ # workflow, this file is vendored there ONCE and every source repo's caller
14
+ # invokes it. Keep it dependency-free (stdlib only) so it drops cleanly into any
15
+ # runner.
16
+ #
17
+ # -----------------------------------------------------------------------------
18
+ # doc-model schema (v1) — the contract every extractor must emit:
19
+ # {
20
+ # "source": "python-sdk" | "ts-sdk" | "cli",
21
+ # "package": "bedrock-agentcore",
22
+ # "version": "1.16.0",
23
+ # "language": "python" | "typescript" | "cli",
24
+ # "groups": [ # a group -> one .adoc file
25
+ # {
26
+ # "id": "runtime", # -> <prefix>-runtime.adoc, and anchor id
27
+ # "title": "Runtime",
28
+ # "summary": "Runtime management and application context.",
29
+ # "entries": [ # classes / functions / commands
30
+ # {
31
+ # "kind": "class" | "function" | "command",
32
+ # "name": "BedrockAgentCoreApp",
33
+ # "signature": "BedrockAgentCoreApp(params)",
34
+ # "summary": "one-line summary",
35
+ # "description": "longer prose (optional)",
36
+ # "params": [ {"name","type","required","description"} ],
37
+ # "returns": {"type","description"} | null,
38
+ # "raises": [ {"type","description"} ],
39
+ # "examples": [ {"lang","code"} ],
40
+ # "members": [ <entry>, ... ] # methods on a class (recursive)
41
+ # }
42
+ # ]
43
+ # }
44
+ # ]
45
+ # }
46
+ # -----------------------------------------------------------------------------
47
+
48
+ import argparse
49
+ import json
50
+ import os
51
+ import re
52
+ import sys
53
+ import textwrap
54
+
55
+ SCHEMA_VERSION = 1
56
+
57
+
58
+ def normalize_style(text):
59
+ """Apply style-safe substitutions to generated prose."""
60
+ if not text:
61
+ return ""
62
+ text = re.sub(r"\be\.g\.(?:,)?", "for example,", text, flags=re.IGNORECASE)
63
+ text = re.sub(
64
+ r"\bAWS (?:Bedrock(?: AgentCore)? )?Code\s*Interpreter\b",
65
+ "Amazon Bedrock AgentCore Code Interpreter",
66
+ text,
67
+ flags=re.IGNORECASE,
68
+ )
69
+ text = re.sub(r"\bAWS Bedrock AgentCore\b", "Amazon Bedrock AgentCore", text)
70
+ text = re.sub(r"\bAWS Bedrock\b", "Amazon Bedrock", text)
71
+ text = re.sub(
72
+ r"(?<!Amazon )(?<!AWS )\bBedrock AgentCore\b",
73
+ "Amazon Bedrock AgentCore",
74
+ text,
75
+ )
76
+ text = re.sub(
77
+ r"(?<!Amazon Bedrock )\bAgentCore Code Interpreter\b",
78
+ "Amazon Bedrock AgentCore Code Interpreter",
79
+ text,
80
+ )
81
+ text = re.sub(
82
+ r"(?<!Amazon Bedrock )\bAgentCore runtime\b",
83
+ "Amazon Bedrock AgentCore runtime",
84
+ text,
85
+ )
86
+ text = re.sub(
87
+ r"(?<!Amazon Bedrock )\bAgentCore Identity\b",
88
+ "Amazon Bedrock AgentCore Identity",
89
+ text,
90
+ )
91
+ text = text.replace(", allowing applications to", " so applications can")
92
+ text = re.sub(r"\bAWS region\b", "AWS Region", text, flags=re.IGNORECASE)
93
+ text = re.sub(r"\bAgentCore Memory\b", "AgentCore memory", text)
94
+ text = re.sub(r"\bAgentCore Runtime\b", "AgentCore runtime", text)
95
+ text = text.replace(
96
+ "This feature is in preview and may change in future releases.",
97
+ "This feature is in preview and might change in future releases.",
98
+ )
99
+ text = text.replace("validation will ensure", "validation ensures")
100
+ return re.sub(r"\bAWS\b", "{aws}", text)
101
+
102
+
103
+ def normalize_param_description(text):
104
+ """Normalize recurring parameter-description style issues."""
105
+ text = normalize_style(text).strip()
106
+ exact_substitutions = {
107
+ "bedrock, open_ai, or gemini": (
108
+ "The model provider. Valid values: `bedrock`, `open_ai`, or `gemini`."
109
+ ),
110
+ "Override LiteLLM API base URL (harness only, lite_llm) [non-interactive]": (
111
+ "The LiteLLM API base URL override for harness invocations. "
112
+ "Available only with `lite_llm` in non-interactive mode."
113
+ ),
114
+ "Override LiteLLM additional params as a JSON object (harness only, lite_llm) "
115
+ "[non-interactive]": (
116
+ "The additional LiteLLM parameters, as a JSON object, for harness invocations. "
117
+ "Available only with `lite_llm` in non-interactive mode."
118
+ ),
119
+ }
120
+ if text in exact_substitutions:
121
+ return exact_substitutions[text]
122
+ substitutions = (
123
+ (r"^Optional\b", "The optional"),
124
+ (r"^(?:\{aws\}|AWS)\s+region\b", "The {aws} Region"),
125
+ (r"^id of\b", "The ID of"),
126
+ (r"^Behaviour\b", "The behavior"),
127
+ (r"^Behavior\b", "The behavior"),
128
+ (r"^Memory resource ID\b", "The memory resource ID"),
129
+ (r"^Strategy name\b", "The name of the memory strategy"),
130
+ (r"^Strategy ID\b", "The ID of the memory strategy"),
131
+ )
132
+ for pattern, replacement in substitutions:
133
+ text = re.sub(pattern, replacement, text, count=1, flags=re.IGNORECASE)
134
+ return text
135
+ def esc(text):
136
+ """Escape AsciiDoc-significant characters in inline text."""
137
+ if not text:
138
+ return ""
139
+ # Guard the couple of chars that start AsciiDoc markup in running prose.
140
+ marker = "\0AWS_ENTITY\0"
141
+ text = normalize_style(text).replace("{aws}", marker)
142
+ return text.replace("|", "\\|").replace("{", "\\{").replace(marker, "{aws}")
143
+
144
+
145
+ # Match markdown code fences that may be indented (reST/Google docstrings often
146
+ # indent example blocks). `re.MULTILINE` lets ^ match each line start; the
147
+ # leading-whitespace groups are stripped from the captured code.
148
+ _FENCE_RE = re.compile(r"^[ \t]*```(\w*)[ \t]*\n(.*?)\n[ \t]*```[ \t]*$", re.DOTALL | re.MULTILINE)
149
+
150
+
151
+ def render_prose(text):
152
+ """Render description prose that may contain markdown ``` code fences.
153
+
154
+ Docstrings/TSDoc frequently embed fenced code blocks in the description
155
+ (not just in @example). Left alone they leak literal backticks into the
156
+ AsciiDoc. Split the prose on fences: escape the prose spans, and convert
157
+ each fenced block into an AsciiDoc [source] block (verbatim, not escaped).
158
+ """
159
+ if not text:
160
+ return []
161
+ out = []
162
+ pos = 0
163
+ for m in _FENCE_RE.finditer(text):
164
+ before = text[pos:m.start()].strip()
165
+ if before:
166
+ out.append(esc(before))
167
+ out.append("")
168
+ lang = m.group(1) or ""
169
+ out.append(f"[source,{lang}]" if lang else "[source]")
170
+ out.append("----")
171
+ # Dedent the captured code (fences are often indented in docstrings).
172
+ out.append(textwrap.dedent(m.group(2)).rstrip())
173
+ out.append("----")
174
+ out.append("")
175
+ pos = m.end()
176
+ tail = text[pos:].strip()
177
+ if tail:
178
+ out.append(esc(tail))
179
+ return out
180
+
181
+
182
+ def block(lines):
183
+ return "\n".join(lines)
184
+
185
+
186
+ def render_params(params, out):
187
+ if not params:
188
+ return
189
+ out.append("*Parameters*")
190
+ out.append("")
191
+ for p in params:
192
+ req = "" if p.get("required") else " _(optional)_"
193
+ typ = f"`{p['type']}`" if p.get("type") else ""
194
+ out.append(f"`{p['name']}`{req} {typ}::")
195
+ out.append(esc(normalize_param_description(p.get("description", ""))) or "_No description._")
196
+ out.append("")
197
+
198
+
199
+ def render_returns(returns, out):
200
+ if not returns:
201
+ return
202
+ typ = f"`{returns['type']}` — " if returns.get("type") else ""
203
+ out.append("*Returns*")
204
+ out.append("")
205
+ out.append(f"{typ}{esc(returns.get('description', ''))}".strip())
206
+ out.append("")
207
+
208
+
209
+ def render_raises(raises, out):
210
+ if not raises:
211
+ return
212
+ out.append("*Raises*")
213
+ out.append("")
214
+ for r in raises:
215
+ out.append(f"`{r.get('type', 'Error')}`:: {esc(r.get('description', ''))}")
216
+ out.append("")
217
+
218
+
219
+ def clean_example_code(code):
220
+ """Strip stray markdown fence lines from example code.
221
+
222
+ Extractors try to remove ``` fences, but real docstrings put them mid-buffer
223
+ (e.g. a fence followed by extra "Notes:"/"Thread Safety:" prose swept into
224
+ the example). Since this text is already going inside an AsciiDoc [source]
225
+ block, any line that is just a fence is spurious — drop it, and drop trailing
226
+ non-code prose that follows a closing fence.
227
+ """
228
+ lines = code.split("\n")
229
+ kept = []
230
+ closed = False
231
+ for line in lines:
232
+ if re.match(r"^[ \t]*```", line):
233
+ # A closing fence marks the end of the real code; ignore the fence
234
+ # line itself and stop taking subsequent prose.
235
+ if kept:
236
+ closed = True
237
+ continue
238
+ if closed and line.strip() == "":
239
+ continue
240
+ if closed and line.strip():
241
+ break # prose after the closing fence — not part of the example
242
+ kept.append(line)
243
+ return textwrap.dedent("\n".join(kept)).strip()
244
+
245
+
246
+ def render_examples(examples, out):
247
+ for ex in examples or []:
248
+ lang = ex.get("lang", "text")
249
+ code = clean_example_code(ex.get("code", ""))
250
+ if not code:
251
+ continue
252
+ out.append(f"[source,{lang}]")
253
+ out.append("----")
254
+ out.append(code)
255
+ out.append("----")
256
+ out.append("")
257
+
258
+
259
+ def render_entry(entry, level, out):
260
+ """Render a single class/function/command as an AsciiDoc section."""
261
+ heading = "=" * level
262
+ name = entry.get("name", "")
263
+ out.append(f"{heading} {name}")
264
+ out.append("")
265
+
266
+ sig = entry.get("signature")
267
+ if sig:
268
+ out.append("[source]")
269
+ out.append("----")
270
+ out.append(sig)
271
+ out.append("----")
272
+ out.append("")
273
+
274
+ if entry.get("summary"):
275
+ out.extend(render_prose(entry["summary"]))
276
+ out.append("")
277
+ if entry.get("description"):
278
+ out.extend(render_prose(entry["description"]))
279
+ out.append("")
280
+
281
+ render_params(entry.get("params"), out)
282
+ render_returns(entry.get("returns"), out)
283
+ render_raises(entry.get("raises"), out)
284
+ render_examples(entry.get("examples"), out)
285
+
286
+ # methods / subcommands nest one heading level deeper
287
+ for member in entry.get("members", []):
288
+ render_entry(member, level + 1, out)
289
+
290
+
291
+ def render_group(group, model, prefix):
292
+ """Render one group -> one .adoc file body (string)."""
293
+ out = []
294
+ gid = group["id"]
295
+ # AsciiDoc anchor so the TOC / other pages can xref into it.
296
+ out.append(f"[[{prefix}-{gid}]]")
297
+ out.append(f"= {group['title']}")
298
+ out.append("")
299
+ out.append(
300
+ f"_Auto-generated from `{model['package']}` "
301
+ f"v{model['version']} — do not edit by hand._"
302
+ )
303
+ out.append("")
304
+ if group.get("summary"):
305
+ out.extend(render_prose(group["summary"]))
306
+ out.append("")
307
+
308
+ for entry in group.get("entries", []):
309
+ render_entry(entry, level=2, out=out)
310
+
311
+ return block(out).rstrip() + "\n"
312
+
313
+
314
+ def main():
315
+ ap = argparse.ArgumentParser(description="Render doc-model JSON to .adoc")
316
+ ap.add_argument("--model", required=True, help="path to doc-model JSON")
317
+ ap.add_argument("--out-dir", required=True, help="output dir for .adoc files")
318
+ ap.add_argument(
319
+ "--prefix",
320
+ required=True,
321
+ help="filename + anchor prefix, e.g. 'python-sdk', 'ts-sdk', 'cli'",
322
+ )
323
+ args = ap.parse_args()
324
+
325
+ with open(args.model) as f:
326
+ model = json.load(f)
327
+
328
+ os.makedirs(args.out_dir, exist_ok=True)
329
+ written = []
330
+ for group in model.get("groups", []):
331
+ body = render_group(group, model, args.prefix)
332
+ fname = f"{args.prefix}-{group['id']}.adoc"
333
+ path = os.path.join(args.out_dir, fname)
334
+ with open(path, "w") as f:
335
+ f.write(body)
336
+ written.append(fname)
337
+
338
+ # Emit the list of includes the caller can splice into the docs TOC file.
339
+ manifest = os.path.join(args.out_dir, f"{args.prefix}-includes.txt")
340
+ with open(manifest, "w") as f:
341
+ for fname in written:
342
+ f.write(f"include::{args.prefix}/{fname}[leveloffset=+1]\n")
343
+
344
+ print(f"Rendered {len(written)} .adoc files to {args.out_dir}", file=sys.stderr)
345
+ for fname in written:
346
+ print(f" - {fname}", file=sys.stderr)
347
+
348
+
349
+ if __name__ == "__main__":
350
+ main()
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env bash
2
+ # Run E2E tests against your dev account using local credentials.
3
+ #
4
+ # Usage:
5
+ # ./scripts/run-e2e-dev.sh # runs strands-bedrock.test.ts
6
+ # ./scripts/run-e2e-dev.sh --all # runs the full e2e suite
7
+ # ./scripts/run-e2e-dev.sh e2e-tests/foo.test.ts # runs a specific test file
8
+
9
+ set -euo pipefail
10
+
11
+ REGION="${AWS_REGION:-us-east-1}"
12
+
13
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
14
+ REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
15
+
16
+ # ── Parse arguments ────────────────────────────────────────────────────────────
17
+ RUN_ALL=false
18
+ TEST_FILES=()
19
+ for arg in "$@"; do
20
+ if [[ "$arg" == "--all" ]]; then
21
+ RUN_ALL=true
22
+ else
23
+ TEST_FILES+=("$arg")
24
+ fi
25
+ done
26
+
27
+ # ── Build & install CLI from source ────────────────────────────────────────────
28
+ cd "$REPO_ROOT"
29
+ npm run build
30
+ TARBALL=$(npm pack | tail -1)
31
+ npm install -g "$TARBALL"
32
+ echo "=== Installed: $(agentcore --version) ==="
33
+
34
+ # ── Set env vars for tests ─────────────────────────────────────────────────────
35
+ export AWS_REGION="$REGION"
36
+ export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
37
+
38
+ # ── Run tests ──────────────────────────────────────────────────────────────────
39
+ cd "$REPO_ROOT"
40
+
41
+ EXCLUDE_API_KEY_TESTS=(
42
+ --exclude 'e2e-tests/*-anthropic*'
43
+ --exclude 'e2e-tests/*-openai*'
44
+ --exclude 'e2e-tests/*-gemini*'
45
+ )
46
+
47
+ if [[ "$RUN_ALL" == "true" ]]; then
48
+ echo "=== Running full e2e suite ==="
49
+ npx vitest run --project e2e
50
+ elif [[ ${#TEST_FILES[@]} -gt 0 ]]; then
51
+ echo "=== Running: ${TEST_FILES[*]} ==="
52
+ npx vitest run --project e2e "${TEST_FILES[@]}"
53
+ else
54
+ echo "=== Running all Bedrock/IAM tests (excluding API-key-dependent tests) ==="
55
+ npx vitest run --project e2e "${EXCLUDE_API_KEY_TESTS[@]}"
56
+ fi
@@ -0,0 +1,145 @@
1
+ #!/usr/bin/env bash
2
+ # Run E2E tests locally in the CI account, replicating the GitHub Actions e2e-tests.yml workflow.
3
+ #
4
+ # Required env vars:
5
+ # E2E_ROLE_ARN — IAM role ARN to assume (grants access to the test account)
6
+ # E2E_SECRET_ARN — Secrets Manager ARN containing ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY,
7
+ # and (for payments tests) CDP_API_KEY_ID, CDP_API_KEY_SECRET, CDP_WALLET_SECRET
8
+ #
9
+ # Optional env vars:
10
+ # AWS_REGION — defaults to us-east-1
11
+ # CDK_REPO_PATH — local path to CDK constructs repo; if set, builds and uses it as CDK_TARBALL
12
+ #
13
+ # Usage:
14
+ # export E2E_ROLE_ARN=arn:aws:iam::<account>:role/<role>
15
+ # export E2E_SECRET_ARN=arn:aws:secretsmanager:<region>:<account>:secret:<name>
16
+ # ./scripts/run-e2e-local.sh # runs strands-bedrock.test.ts (CI default)
17
+ # ./scripts/run-e2e-local.sh --all # runs the full e2e suite
18
+ # ./scripts/run-e2e-local.sh e2e-tests/foo.test.ts # runs a specific test file
19
+ #
20
+ # Prerequisites: aws CLI, node >=20.19, npm, git, uv, jq
21
+
22
+ set -euo pipefail
23
+
24
+ ROLE_ARN="${E2E_ROLE_ARN:-}"
25
+ SECRET_ARN="${E2E_SECRET_ARN:-}"
26
+ AWS_REGION="${AWS_REGION:-us-east-1}"
27
+
28
+ if [[ -z "$ROLE_ARN" ]]; then
29
+ echo "❌ E2E_ROLE_ARN is not set. Export it before running this script:"
30
+ echo " export E2E_ROLE_ARN=arn:aws:iam::<account>:role/<role-name>"
31
+ exit 1
32
+ fi
33
+
34
+ if [[ -z "$SECRET_ARN" ]]; then
35
+ echo "❌ E2E_SECRET_ARN is not set. Export it before running this script:"
36
+ echo " export E2E_SECRET_ARN=arn:aws:secretsmanager:<region>:<account>:secret:<name>"
37
+ exit 1
38
+ fi
39
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
40
+ REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
41
+
42
+ # ── Parse arguments ────────────────────────────────────────────────────────────
43
+ RUN_ALL=false
44
+ TEST_FILES=()
45
+ for arg in "$@"; do
46
+ if [[ "$arg" == "--all" ]]; then
47
+ RUN_ALL=true
48
+ else
49
+ TEST_FILES+=("$arg")
50
+ fi
51
+ done
52
+
53
+ echo "=== Assuming IAM role ==="
54
+ CREDS=$(aws sts assume-role \
55
+ --role-arn "$ROLE_ARN" \
56
+ --role-session-name "local-e2e-$(date +%s)" \
57
+ --duration-seconds 3600 \
58
+ --query 'Credentials.[AccessKeyId,SecretAccessKey,SessionToken]' \
59
+ --output text)
60
+
61
+ export AWS_ACCESS_KEY_ID=$(echo "$CREDS" | awk '{print $1}')
62
+ export AWS_SECRET_ACCESS_KEY=$(echo "$CREDS" | awk '{print $2}')
63
+ export AWS_SESSION_TOKEN=$(echo "$CREDS" | awk '{print $3}')
64
+ export AWS_REGION
65
+
66
+ echo "✅ Assumed role successfully"
67
+
68
+ echo "=== Fetching API keys from Secrets Manager ==="
69
+ SECRET_JSON=$(aws secretsmanager get-secret-value \
70
+ --secret-id "$SECRET_ARN" \
71
+ --region "$AWS_REGION" \
72
+ --query SecretString \
73
+ --output text)
74
+
75
+ # Mirror the GitHub workflow: parse-json-secrets maps keys to E2E_<KEY> then
76
+ # the workflow maps them to the bare names the tests expect.
77
+ export ANTHROPIC_API_KEY=$(echo "$SECRET_JSON" | jq -r '.ANTHROPIC_API_KEY // empty')
78
+ export OPENAI_API_KEY=$(echo "$SECRET_JSON" | jq -r '.OPENAI_API_KEY // empty')
79
+ export GEMINI_API_KEY=$(echo "$SECRET_JSON" | jq -r '.GEMINI_API_KEY // empty')
80
+
81
+ # Filesystem (BYO EFS / S3 Files) test inputs — required by strands-bedrock-byo-filesystem.test.ts.
82
+ export E2E_EFS_ACCESS_POINT_ARN=$(echo "$SECRET_JSON" | jq -r '.EFS_ACCESS_POINT_ARN // empty')
83
+ export E2E_S3_ACCESS_POINT_ARN=$(echo "$SECRET_JSON" | jq -r '.S3_ACCESS_POINT_ARN // empty')
84
+ export E2E_FILESYSTEM_SUBNET_ID=$(echo "$SECRET_JSON" | jq -r '.FILESYSTEM_SUBNET_ID // empty')
85
+ export E2E_FILESYSTEM_SECURITY_GROUP_ID=$(echo "$SECRET_JSON" | jq -r '.FILESYSTEM_SECURITY_GROUP_ID // empty')
86
+
87
+ # Payments (CDP) test inputs — required by payment-strands-bedrock.test.ts.
88
+ export CDP_API_KEY_ID=$(echo "$SECRET_JSON" | jq -r '.CDP_API_KEY_ID // empty')
89
+ export CDP_API_KEY_SECRET=$(echo "$SECRET_JSON" | jq -r '.CDP_API_KEY_SECRET // empty')
90
+ export CDP_WALLET_SECRET=$(echo "$SECRET_JSON" | jq -r '.CDP_WALLET_SECRET // empty')
91
+
92
+ echo "✅ Secrets loaded (keys present: $(echo "$SECRET_JSON" | jq -r 'keys | join(", ")')"
93
+
94
+ echo "=== Setting AWS account env var ==="
95
+ export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
96
+ echo "✅ AWS_ACCOUNT_ID=$AWS_ACCOUNT_ID AWS_REGION=$AWS_REGION"
97
+
98
+ cd "$REPO_ROOT"
99
+
100
+ echo "=== Verifying git is configured (required for agentcore create) ==="
101
+ git_email="$(git config --global user.email || true)"
102
+ git_name="$(git config --global user.name || true)"
103
+
104
+ if [ -z "$git_email" ] || [ -z "$git_name" ]; then
105
+ echo "ERROR: git is not configured. 'agentcore create' requires a global git identity." >&2
106
+ echo "Set it with:" >&2
107
+ echo " git config --global user.email \"you@example.com\"" >&2
108
+ echo " git config --global user.name \"Your Name\"" >&2
109
+ exit 1
110
+ fi
111
+
112
+ echo "git configured as: $git_name <$git_email>"
113
+
114
+ echo "=== Installing dependencies ==="
115
+ npm ci
116
+
117
+ echo "=== Building CLI ==="
118
+ npm run build
119
+
120
+ echo "=== Installing CLI globally ==="
121
+ TARBALL=$(npm pack | tail -1)
122
+ npm install -g "$TARBALL"
123
+ echo "✅ Installed: $(agentcore --version)"
124
+
125
+ echo "=== Running E2E tests ==="
126
+ if [[ -n "${CDK_REPO_PATH:-}" ]]; then
127
+ echo "=== Building CDK constructs from $CDK_REPO_PATH ==="
128
+ pushd "$CDK_REPO_PATH" > /dev/null
129
+ npm ci
130
+ npm run build
131
+ CDK_TARBALL_NAME=$(npm pack | tail -1)
132
+ export CDK_TARBALL="$CDK_REPO_PATH/$CDK_TARBALL_NAME"
133
+ popd > /dev/null
134
+ echo "✅ CDK_TARBALL=$CDK_TARBALL"
135
+ fi
136
+ if [[ "$RUN_ALL" == "true" ]]; then
137
+ echo "Running full e2e suite"
138
+ npx vitest run --project e2e
139
+ elif [[ ${#TEST_FILES[@]} -gt 0 ]]; then
140
+ echo "Running: ${TEST_FILES[*]}"
141
+ npx vitest run --project e2e "${TEST_FILES[@]}"
142
+ else
143
+ echo "Running default: e2e-tests/strands-bedrock.test.ts"
144
+ npx vitest run --project e2e e2e-tests/strands-bedrock.test.ts
145
+ fi
@@ -0,0 +1,7 @@
1
+ import { JUnitReporter } from 'vitest/node';
2
+
3
+ export default class SafeJUnitReporter extends JUnitReporter {
4
+ constructor() {
5
+ super({ includeConsoleOutput: false });
6
+ }
7
+ }
@@ -0,0 +1,65 @@
1
+ import { redactTestOutput, sensitiveEnvironmentValues } from '../src/test-utils/test-output-redaction';
2
+ import { lstat, readFile, readdir, writeFile } from 'node:fs/promises';
3
+ import { relative, resolve } from 'node:path';
4
+
5
+ type Mode = 'check' | 'redact';
6
+
7
+ async function collectFiles(inputPath: string): Promise<string[]> {
8
+ const absolutePath = resolve(inputPath);
9
+
10
+ try {
11
+ const fileStat = await lstat(absolutePath);
12
+ if (fileStat.isSymbolicLink()) {
13
+ throw new Error(`Symbolic links are not allowed in test artifacts: ${inputPath}`);
14
+ }
15
+ if (fileStat.isFile()) return [absolutePath];
16
+ if (!fileStat.isDirectory()) return [];
17
+ } catch (error) {
18
+ if ((error as NodeJS.ErrnoException).code === 'ENOENT') return [];
19
+ throw error;
20
+ }
21
+
22
+ const entries = await readdir(absolutePath, { withFileTypes: true });
23
+ const files = await Promise.all(entries.map(entry => collectFiles(resolve(absolutePath, entry.name))));
24
+ return files.flat();
25
+ }
26
+
27
+ async function main(): Promise<void> {
28
+ const [modeArgument, ...inputPaths] = process.argv.slice(2);
29
+ if ((modeArgument !== '--redact' && modeArgument !== '--check') || inputPaths.length === 0) {
30
+ throw new Error('Usage: tsx scripts/sanitize-test-artifacts.ts <--redact|--check> <path...>');
31
+ }
32
+
33
+ const mode = modeArgument.slice(2) as Mode;
34
+ const files = (await Promise.all(inputPaths.map(collectFiles))).flat();
35
+ const secretValues = sensitiveEnvironmentValues();
36
+ const affectedFiles: string[] = [];
37
+ let redactionCount = 0;
38
+
39
+ for (const file of files) {
40
+ const original = await readFile(file, 'utf8');
41
+ const result = redactTestOutput(original, secretValues);
42
+ if (result.redactions === 0) continue;
43
+
44
+ affectedFiles.push(relative(process.cwd(), file));
45
+ redactionCount += result.redactions;
46
+ if (mode === 'redact') await writeFile(file, result.text, 'utf8');
47
+ }
48
+
49
+ if (mode === 'check' && affectedFiles.length > 0) {
50
+ console.error(`Sensitive output detected in ${affectedFiles.length} artifact file(s): ${affectedFiles.join(', ')}`);
51
+ process.exitCode = 1;
52
+ return;
53
+ }
54
+
55
+ if (mode === 'redact') {
56
+ console.log(`Redacted ${redactionCount} sensitive value(s) from ${affectedFiles.length} artifact file(s).`);
57
+ } else {
58
+ console.log(`No sensitive output detected in ${files.length} artifact file(s).`);
59
+ }
60
+ }
61
+
62
+ void main().catch((error: unknown) => {
63
+ console.error(error instanceof Error ? error.message : String(error));
64
+ process.exitCode = 1;
65
+ });