agent-starter-pack 0.3.3__py3-none-any.whl → 0.21.0__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 (255) hide show
  1. agent_starter_pack/agents/README.md +7 -0
  2. agents/langgraph_base_react/template/.templateconfig.yaml → agent_starter_pack/agents/adk_a2a_base/.template/templateconfig.yaml +5 -10
  3. agent_starter_pack/agents/adk_a2a_base/README.md +37 -0
  4. src/deployment_targets/cloud_run/Dockerfile → agent_starter_pack/agents/adk_a2a_base/app/__init__.py +2 -14
  5. agent_starter_pack/agents/adk_a2a_base/app/agent.py +70 -0
  6. agent_starter_pack/agents/adk_a2a_base/notebooks/adk_a2a_app_testing.ipynb +583 -0
  7. agents/crewai_coding_crew/notebooks/evaluating_crewai_agent.ipynb → agent_starter_pack/agents/adk_a2a_base/notebooks/evaluating_adk_agent.ipynb +163 -199
  8. {agents/adk_base → agent_starter_pack/agents/adk_a2a_base}/tests/integration/test_agent.py +2 -2
  9. agents/adk_base/template/.templateconfig.yaml → agent_starter_pack/agents/adk_base/.template/templateconfig.yaml +4 -1
  10. {agents → agent_starter_pack/agents}/adk_base/README.md +1 -1
  11. agent_starter_pack/agents/adk_base/app/__init__.py +17 -0
  12. {agents → agent_starter_pack/agents}/adk_base/app/agent.py +5 -2
  13. {agents → agent_starter_pack/agents}/adk_base/notebooks/adk_app_testing.ipynb +128 -82
  14. agents/langgraph_base_react/notebooks/evaluating_langgraph_agent.ipynb → agent_starter_pack/agents/adk_base/notebooks/evaluating_adk_agent.ipynb +181 -207
  15. agent_starter_pack/agents/adk_base/tests/integration/test_agent.py +58 -0
  16. agents/crewai_coding_crew/template/.templateconfig.yaml → agent_starter_pack/agents/adk_live/.template/templateconfig.yaml +5 -9
  17. agent_starter_pack/agents/adk_live/README.md +32 -0
  18. agent_starter_pack/agents/adk_live/app/__init__.py +17 -0
  19. agent_starter_pack/agents/adk_live/app/agent.py +51 -0
  20. agent_starter_pack/agents/adk_live/tests/unit/test_dummy.py +38 -0
  21. agents/agentic_rag/template/.templateconfig.yaml → agent_starter_pack/agents/agentic_rag/.template/templateconfig.yaml +7 -3
  22. {agents → agent_starter_pack/agents}/agentic_rag/README.md +1 -1
  23. agent_starter_pack/agents/agentic_rag/app/__init__.py +17 -0
  24. {agents → agent_starter_pack/agents}/agentic_rag/app/agent.py +8 -4
  25. {agents → agent_starter_pack/agents}/agentic_rag/notebooks/adk_app_testing.ipynb +128 -82
  26. agent_starter_pack/agents/agentic_rag/notebooks/evaluating_adk_agent.ipynb +1535 -0
  27. {agents → agent_starter_pack/agents}/agentic_rag/tests/integration/test_agent.py +3 -3
  28. agent_starter_pack/agents/langgraph_base/.template/templateconfig.yaml +31 -0
  29. agent_starter_pack/agents/langgraph_base/README.md +30 -0
  30. agent_starter_pack/agents/langgraph_base/app/__init__.py +17 -0
  31. agent_starter_pack/agents/langgraph_base/app/agent.py +34 -0
  32. {agents/crewai_coding_crew → agent_starter_pack/agents/langgraph_base}/notebooks/evaluating_langgraph_agent.ipynb +30 -17
  33. {agents/langgraph_base_react → agent_starter_pack/agents/langgraph_base}/tests/integration/test_agent.py +2 -2
  34. {src → agent_starter_pack}/base_template/.gitignore +5 -3
  35. agent_starter_pack/base_template/GEMINI.md +5 -0
  36. agent_starter_pack/base_template/Makefile +339 -0
  37. agent_starter_pack/base_template/README.md +267 -0
  38. agent_starter_pack/base_template/deployment/README.md +11 -0
  39. {src → agent_starter_pack}/base_template/deployment/terraform/apis.tf +2 -2
  40. {src → agent_starter_pack}/base_template/deployment/terraform/dev/apis.tf +6 -1
  41. {src → agent_starter_pack}/base_template/deployment/terraform/dev/iam.tf +12 -11
  42. {src → agent_starter_pack}/base_template/deployment/terraform/dev/providers.tf +5 -1
  43. {src → agent_starter_pack}/base_template/deployment/terraform/dev/storage.tf +1 -1
  44. {src → agent_starter_pack}/base_template/deployment/terraform/dev/variables.tf +10 -10
  45. agent_starter_pack/base_template/deployment/terraform/dev/{% if cookiecutter.is_adk %}telemetry.tf{% else %}unused_telemetry.tf{% endif %} +193 -0
  46. agent_starter_pack/base_template/deployment/terraform/github.tf +337 -0
  47. {src → agent_starter_pack}/base_template/deployment/terraform/iam.tf +20 -41
  48. {src → agent_starter_pack}/base_template/deployment/terraform/locals.tf +10 -3
  49. {src/resources/setup_cicd → agent_starter_pack/base_template/deployment/terraform}/providers.tf +8 -1
  50. {src → agent_starter_pack}/base_template/deployment/terraform/service_accounts.tf +7 -8
  51. agent_starter_pack/base_template/deployment/terraform/sql/completions.sql +138 -0
  52. {src → agent_starter_pack}/base_template/deployment/terraform/storage.tf +7 -16
  53. {src → agent_starter_pack}/base_template/deployment/terraform/variables.tf +61 -28
  54. {src → agent_starter_pack}/base_template/deployment/terraform/vars/env.tfvars +6 -1
  55. agent_starter_pack/base_template/deployment/terraform/{% if cookiecutter.cicd_runner == 'github_actions' %}wif.tf{% else %}unused_wif.tf{% endif %} +43 -0
  56. src/base_template/deployment/terraform/build_triggers.tf → agent_starter_pack/base_template/deployment/terraform/{% if cookiecutter.cicd_runner == 'google_cloud_build' %}build_triggers.tf{% else %}unused_build_triggers.tf{% endif %} +55 -38
  57. agent_starter_pack/base_template/deployment/terraform/{% if cookiecutter.is_adk %}telemetry.tf{% else %}unused_telemetry.tf{% endif %} +206 -0
  58. {src → agent_starter_pack}/base_template/pyproject.toml +24 -37
  59. agent_starter_pack/base_template/{% if cookiecutter.cicd_runner == 'github_actions' %}.github{% else %}unused_github{% endif %}/workflows/deploy-to-prod.yaml +132 -0
  60. agent_starter_pack/base_template/{% if cookiecutter.cicd_runner == 'github_actions' %}.github{% else %}unused_github{% endif %}/workflows/pr_checks.yaml +65 -0
  61. agent_starter_pack/base_template/{% if cookiecutter.cicd_runner == 'github_actions' %}.github{% else %}unused_github{% endif %}/workflows/staging.yaml +259 -0
  62. src/base_template/deployment/cd/deploy-to-prod.yaml → agent_starter_pack/base_template/{% if cookiecutter.cicd_runner == 'google_cloud_build' %}.cloudbuild{% else %}unused_.cloudbuild{% endif %}/deploy-to-prod.yaml +38 -30
  63. src/base_template/deployment/ci/pr_checks.yaml → agent_starter_pack/base_template/{% if cookiecutter.cicd_runner == 'google_cloud_build' %}.cloudbuild{% else %}unused_.cloudbuild{% endif %}/pr_checks.yaml +5 -5
  64. agent_starter_pack/base_template/{% if cookiecutter.cicd_runner == 'google_cloud_build' %}.cloudbuild{% else %}unused_.cloudbuild{% endif %}/staging.yaml +322 -0
  65. agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/app_utils/telemetry.py +96 -0
  66. {src/base_template/app/utils → agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/app_utils}/typing.py +7 -9
  67. agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/app_utils/{% if cookiecutter.is_a2a and cookiecutter.agent_name == 'langgraph_base' %}converters{% else %}unused_converters{% endif %}/__init__.py +25 -0
  68. agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/app_utils/{% if cookiecutter.is_a2a and cookiecutter.agent_name == 'langgraph_base' %}converters{% else %}unused_converters{% endif %}/part_converter.py +138 -0
  69. agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/app_utils/{% if cookiecutter.is_a2a and cookiecutter.agent_name == 'langgraph_base' %}executor{% else %}unused_executor{% endif %}/__init__.py +13 -0
  70. agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/app_utils/{% if cookiecutter.is_a2a and cookiecutter.agent_name == 'langgraph_base' %}executor{% else %}unused_executor{% endif %}/a2a_agent_executor.py +265 -0
  71. agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/app_utils/{% if cookiecutter.is_a2a and cookiecutter.agent_name == 'langgraph_base' %}executor{% else %}unused_executor{% endif %}/task_result_aggregator.py +152 -0
  72. agent_starter_pack/cli/commands/create.py +1256 -0
  73. agent_starter_pack/cli/commands/enhance.py +611 -0
  74. agent_starter_pack/cli/commands/list.py +203 -0
  75. agent_starter_pack/cli/commands/register_gemini_enterprise.py +1070 -0
  76. agent_starter_pack/cli/commands/setup_cicd.py +862 -0
  77. {src → agent_starter_pack}/cli/main.py +10 -2
  78. {src → agent_starter_pack}/cli/utils/cicd.py +139 -48
  79. agent_starter_pack/cli/utils/gcp.py +263 -0
  80. agent_starter_pack/cli/utils/logging.py +103 -0
  81. agent_starter_pack/cli/utils/remote_template.py +677 -0
  82. agent_starter_pack/cli/utils/template.py +1466 -0
  83. {src → agent_starter_pack}/data_ingestion/data_ingestion_pipeline/components/process_data.py +1 -1
  84. {src → agent_starter_pack}/data_ingestion/data_ingestion_pipeline/submit_pipeline.py +20 -6
  85. {src → agent_starter_pack}/data_ingestion/pyproject.toml +1 -0
  86. {src → agent_starter_pack}/data_ingestion/uv.lock +602 -494
  87. agent_starter_pack/deployment_targets/agent_engine/tests/integration/test_agent_engine_app.py +484 -0
  88. agent_starter_pack/deployment_targets/agent_engine/tests/load_test/README.md +84 -0
  89. agent_starter_pack/deployment_targets/agent_engine/tests/load_test/load_test.py +424 -0
  90. agent_starter_pack/deployment_targets/agent_engine/tests/{% if cookiecutter.is_a2a %}helpers.py{% else %}unused_helpers.py{% endif %} +138 -0
  91. agent_starter_pack/deployment_targets/agent_engine/{{cookiecutter.agent_directory}}/agent_engine_app.py +263 -0
  92. agent_starter_pack/deployment_targets/agent_engine/{{cookiecutter.agent_directory}}/app_utils/deploy.py +414 -0
  93. agent_starter_pack/deployment_targets/agent_engine/{{cookiecutter.agent_directory}}/app_utils/{% if cookiecutter.is_adk_live %}expose_app.py{% else %}unused_expose_app.py{% endif %} +519 -0
  94. agent_starter_pack/deployment_targets/cloud_run/Dockerfile +51 -0
  95. agent_starter_pack/deployment_targets/cloud_run/deployment/terraform/dev/service.tf +243 -0
  96. agent_starter_pack/deployment_targets/cloud_run/deployment/terraform/service.tf +417 -0
  97. agent_starter_pack/deployment_targets/cloud_run/tests/integration/test_server_e2e.py +705 -0
  98. agent_starter_pack/deployment_targets/cloud_run/tests/load_test/.results/.placeholder +321 -0
  99. agent_starter_pack/deployment_targets/cloud_run/tests/load_test/README.md +165 -0
  100. agent_starter_pack/deployment_targets/cloud_run/tests/load_test/load_test.py +329 -0
  101. agent_starter_pack/deployment_targets/cloud_run/{{cookiecutter.agent_directory}}/fast_api_app.py +556 -0
  102. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/package-lock.json +79 -1044
  103. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/package.json +1 -9
  104. agent_starter_pack/frontends/adk_live_react/frontend/src/App.tsx +65 -0
  105. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/components/logger/Logger.tsx +8 -3
  106. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/components/logger/logger.scss +26 -0
  107. agent_starter_pack/frontends/adk_live_react/frontend/src/components/side-panel/SidePanel.tsx +516 -0
  108. agent_starter_pack/frontends/adk_live_react/frontend/src/components/side-panel/side-panel.scss +563 -0
  109. agent_starter_pack/frontends/adk_live_react/frontend/src/components/transcription-preview/TranscriptionPreview.tsx +106 -0
  110. agent_starter_pack/frontends/adk_live_react/frontend/src/components/transcription-preview/transcription-preview.scss +150 -0
  111. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/hooks/use-live-api.ts +8 -2
  112. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/multimodal-live-types.ts +40 -2
  113. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/utils/audio-recorder.ts +1 -1
  114. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/utils/audio-streamer.ts +1 -1
  115. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/utils/multimodal-live-client.ts +210 -24
  116. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/utils/utils.ts +27 -5
  117. agent_starter_pack/resources/docs/adk-cheatsheet.md +1628 -0
  118. agent_starter_pack/resources/locks/uv-adk_a2a_base-agent_engine.lock +4966 -0
  119. agent_starter_pack/resources/locks/uv-adk_a2a_base-cloud_run.lock +5011 -0
  120. agent_starter_pack/resources/locks/uv-adk_base-agent_engine.lock +4946 -0
  121. agent_starter_pack/resources/locks/uv-adk_base-cloud_run.lock +4991 -0
  122. agent_starter_pack/resources/locks/uv-adk_live-agent_engine.lock +4963 -0
  123. agent_starter_pack/resources/locks/uv-adk_live-cloud_run.lock +5006 -0
  124. agent_starter_pack/resources/locks/uv-agentic_rag-agent_engine.lock +5487 -0
  125. agent_starter_pack/resources/locks/uv-agentic_rag-cloud_run.lock +5532 -0
  126. agent_starter_pack/resources/locks/uv-langgraph_base-agent_engine.lock +5788 -0
  127. agent_starter_pack/resources/locks/uv-langgraph_base-cloud_run.lock +5811 -0
  128. {src → agent_starter_pack}/utils/generate_locks.py +15 -12
  129. {src → agent_starter_pack}/utils/lock_utils.py +4 -7
  130. {src → agent_starter_pack}/utils/watch_and_rebuild.py +2 -2
  131. agent_starter_pack-0.21.0.dist-info/METADATA +182 -0
  132. agent_starter_pack-0.21.0.dist-info/RECORD +171 -0
  133. agent_starter_pack-0.21.0.dist-info/entry_points.txt +2 -0
  134. llm.txt +362 -0
  135. agent_starter_pack-0.3.3.dist-info/METADATA +0 -164
  136. agent_starter_pack-0.3.3.dist-info/RECORD +0 -176
  137. agent_starter_pack-0.3.3.dist-info/entry_points.txt +0 -2
  138. agents/crewai_coding_crew/README.md +0 -34
  139. agents/crewai_coding_crew/app/agent.py +0 -86
  140. agents/crewai_coding_crew/app/crew/config/agents.yaml +0 -39
  141. agents/crewai_coding_crew/app/crew/config/tasks.yaml +0 -37
  142. agents/crewai_coding_crew/app/crew/crew.py +0 -71
  143. agents/crewai_coding_crew/tests/integration/test_agent.py +0 -47
  144. agents/langgraph_base_react/README.md +0 -9
  145. agents/langgraph_base_react/app/agent.py +0 -73
  146. agents/live_api/README.md +0 -37
  147. agents/live_api/app/agent.py +0 -78
  148. agents/live_api/app/server.py +0 -196
  149. agents/live_api/app/templates.py +0 -51
  150. agents/live_api/app/vector_store.py +0 -55
  151. agents/live_api/template/.templateconfig.yaml +0 -29
  152. agents/live_api/tests/integration/test_server_e2e.py +0 -254
  153. agents/live_api/tests/load_test/load_test.py +0 -40
  154. agents/live_api/tests/unit/test_server.py +0 -143
  155. src/base_template/Makefile +0 -72
  156. src/base_template/README.md +0 -208
  157. src/base_template/app/__init__.py +0 -3
  158. src/base_template/app/utils/tracing.py +0 -155
  159. src/base_template/deployment/README.md +0 -126
  160. src/base_template/deployment/cd/staging.yaml +0 -216
  161. src/base_template/deployment/terraform/dev/log_sinks.tf +0 -63
  162. src/base_template/deployment/terraform/log_sinks.tf +0 -70
  163. src/base_template/deployment/terraform/providers.tf +0 -37
  164. src/cli/commands/create.py +0 -664
  165. src/cli/commands/setup_cicd.py +0 -829
  166. src/cli/utils/gcp.py +0 -117
  167. src/cli/utils/logging.py +0 -51
  168. src/cli/utils/template.py +0 -737
  169. src/deployment_targets/agent_engine/app/agent_engine_app.py +0 -336
  170. src/deployment_targets/agent_engine/notebooks/intro_agent_engine.ipynb +0 -1025
  171. src/deployment_targets/agent_engine/tests/integration/test_agent_engine_app.py +0 -183
  172. src/deployment_targets/agent_engine/tests/load_test/README.md +0 -42
  173. src/deployment_targets/agent_engine/tests/load_test/load_test.py +0 -107
  174. src/deployment_targets/cloud_run/app/server.py +0 -154
  175. src/deployment_targets/cloud_run/tests/integration/test_server_e2e.py +0 -249
  176. src/deployment_targets/cloud_run/tests/load_test/.results/.placeholder +0 -0
  177. src/deployment_targets/cloud_run/tests/load_test/README.md +0 -83
  178. src/deployment_targets/cloud_run/tests/load_test/load_test.py +0 -118
  179. src/deployment_targets/cloud_run/uv.lock +0 -6952
  180. src/frontends/live_api_react/frontend/src/App.tsx +0 -205
  181. src/frontends/live_api_react/frontend/src/components/control-tray/ControlTray.tsx +0 -217
  182. src/frontends/live_api_react/frontend/src/components/control-tray/control-tray.scss +0 -201
  183. src/frontends/live_api_react/frontend/src/components/side-panel/SidePanel.tsx +0 -161
  184. src/frontends/live_api_react/frontend/src/components/side-panel/side-panel.scss +0 -285
  185. src/frontends/streamlit/frontend/side_bar.py +0 -214
  186. src/frontends/streamlit/frontend/streamlit_app.py +0 -265
  187. src/frontends/streamlit/frontend/style/app_markdown.py +0 -37
  188. src/frontends/streamlit/frontend/utils/chat_utils.py +0 -67
  189. src/frontends/streamlit/frontend/utils/local_chat_history.py +0 -125
  190. src/frontends/streamlit/frontend/utils/message_editing.py +0 -59
  191. src/frontends/streamlit/frontend/utils/multimodal_utils.py +0 -217
  192. src/frontends/streamlit/frontend/utils/stream_handler.py +0 -301
  193. src/frontends/streamlit/frontend/utils/title_summary.py +0 -94
  194. src/frontends/streamlit_adk/frontend/side_bar.py +0 -214
  195. src/frontends/streamlit_adk/frontend/streamlit_app.py +0 -314
  196. src/frontends/streamlit_adk/frontend/style/app_markdown.py +0 -37
  197. src/frontends/streamlit_adk/frontend/utils/chat_utils.py +0 -84
  198. src/frontends/streamlit_adk/frontend/utils/local_chat_history.py +0 -110
  199. src/frontends/streamlit_adk/frontend/utils/message_editing.py +0 -61
  200. src/frontends/streamlit_adk/frontend/utils/multimodal_utils.py +0 -223
  201. src/frontends/streamlit_adk/frontend/utils/stream_handler.py +0 -311
  202. src/frontends/streamlit_adk/frontend/utils/title_summary.py +0 -129
  203. src/resources/containers/data_processing/Dockerfile +0 -27
  204. src/resources/containers/e2e-tests/Dockerfile +0 -19
  205. src/resources/idx/.idx/dev.nix +0 -57
  206. src/resources/idx/idx-template.json +0 -21
  207. src/resources/idx/idx-template.nix +0 -26
  208. src/resources/locks/uv-adk_base-agent_engine.lock +0 -5338
  209. src/resources/locks/uv-adk_base-cloud_run.lock +0 -5930
  210. src/resources/locks/uv-agentic_rag-agent_engine.lock +0 -5528
  211. src/resources/locks/uv-agentic_rag-cloud_run.lock +0 -6120
  212. src/resources/locks/uv-crewai_coding_crew-agent_engine.lock +0 -6231
  213. src/resources/locks/uv-crewai_coding_crew-cloud_run.lock +0 -6839
  214. src/resources/locks/uv-langgraph_base_react-agent_engine.lock +0 -5233
  215. src/resources/locks/uv-langgraph_base_react-cloud_run.lock +0 -5862
  216. src/resources/locks/uv-live_api-cloud_run.lock +0 -5832
  217. src/resources/setup_cicd/cicd_variables.tf +0 -41
  218. src/resources/setup_cicd/github.tf +0 -87
  219. {agents → agent_starter_pack/agents}/agentic_rag/app/retrievers.py +0 -0
  220. {agents → agent_starter_pack/agents}/agentic_rag/app/templates.py +0 -0
  221. {src → agent_starter_pack}/base_template/deployment/terraform/dev/vars/env.tfvars +0 -0
  222. {src → agent_starter_pack}/base_template/tests/unit/test_dummy.py +0 -0
  223. {src/deployment_targets/agent_engine/app/utils → agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/app_utils}/gcs.py +0 -0
  224. {src → agent_starter_pack}/cli/utils/__init__.py +0 -0
  225. {src → agent_starter_pack}/cli/utils/datastores.py +0 -0
  226. {src → agent_starter_pack}/cli/utils/version.py +0 -0
  227. {src → agent_starter_pack}/data_ingestion/README.md +0 -0
  228. {src → agent_starter_pack}/data_ingestion/data_ingestion_pipeline/components/ingest_data.py +0 -0
  229. {src → agent_starter_pack}/data_ingestion/data_ingestion_pipeline/pipeline.py +0 -0
  230. {src → agent_starter_pack}/deployment_targets/agent_engine/deployment_metadata.json +0 -0
  231. {src → agent_starter_pack}/deployment_targets/agent_engine/tests/load_test/.results/.placeholder +0 -0
  232. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/public/favicon.ico +0 -0
  233. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/public/index.html +0 -0
  234. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/public/robots.txt +0 -0
  235. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/App.scss +0 -0
  236. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/App.test.tsx +0 -0
  237. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/components/audio-pulse/AudioPulse.tsx +0 -0
  238. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/components/audio-pulse/audio-pulse.scss +0 -0
  239. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/components/logger/mock-logs.ts +0 -0
  240. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/contexts/LiveAPIContext.tsx +0 -0
  241. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/hooks/use-media-stream-mux.ts +0 -0
  242. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/hooks/use-screen-capture.ts +0 -0
  243. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/hooks/use-webcam.ts +0 -0
  244. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/index.css +0 -0
  245. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/index.tsx +0 -0
  246. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/react-app-env.d.ts +0 -0
  247. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/reportWebVitals.ts +0 -0
  248. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/setupTests.ts +0 -0
  249. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/utils/audioworklet-registry.ts +0 -0
  250. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/utils/store-logger.ts +0 -0
  251. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/utils/worklets/audio-processing.ts +0 -0
  252. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/utils/worklets/vol-meter.ts +0 -0
  253. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/tsconfig.json +0 -0
  254. {agent_starter_pack-0.3.3.dist-info → agent_starter_pack-0.21.0.dist-info}/WHEEL +0 -0
  255. {agent_starter_pack-0.3.3.dist-info → agent_starter_pack-0.21.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,424 @@
1
+ # Copyright 2025 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ {%- if cookiecutter.agent_name == "adk_live" %}
15
+
16
+ import json
17
+ import logging
18
+ import time
19
+
20
+ from locust import User, between, task
21
+ from websockets.exceptions import WebSocketException
22
+ from websockets.sync.client import connect
23
+
24
+ logging.basicConfig(level=logging.INFO)
25
+ logger = logging.getLogger(__name__)
26
+
27
+
28
+ class WebSocketUser(User):
29
+ """Simulates a user making websocket requests to the remote agent engine."""
30
+
31
+ wait_time = between(1, 3) # Wait 1-3 seconds between tasks
32
+ abstract = True
33
+
34
+ def __init__(self, *args: object, **kwargs: object) -> None:
35
+ super().__init__(*args, **kwargs)
36
+ if self.host.startswith("https://"):
37
+ self.ws_url = self.host.replace("https://", "wss://", 1) + "/ws"
38
+ elif self.host.startswith("http://"):
39
+ self.ws_url = self.host.replace("http://", "ws://", 1) + "/ws"
40
+ else:
41
+ self.ws_url = self.host + "/ws"
42
+
43
+ @task
44
+ def websocket_audio_conversation(self) -> None:
45
+ """Test a full websocket conversation with audio input."""
46
+ start_time = time.time()
47
+ response_count = 0
48
+ exception = None
49
+
50
+ try:
51
+ response_count = self._websocket_interaction()
52
+
53
+ # Mark as failure if we got no valid responses
54
+ if response_count == 0:
55
+ exception = Exception("No responses received from agent")
56
+
57
+ except WebSocketException as e:
58
+ exception = e
59
+ logger.error(f"WebSocket error: {e}")
60
+ except Exception as e:
61
+ exception = e
62
+ logger.error(f"Unexpected error: {e}")
63
+ finally:
64
+ total_time = int((time.time() - start_time) * 1000)
65
+
66
+ # Report the request metrics to Locust
67
+ self.environment.events.request.fire(
68
+ request_type="WS",
69
+ name="websocket_conversation",
70
+ response_time=total_time,
71
+ response_length=response_count * 100, # Approximate response size
72
+ response=None,
73
+ context={},
74
+ exception=exception,
75
+ )
76
+
77
+ def _websocket_interaction(self) -> int:
78
+ """Handle the websocket interaction and return response count."""
79
+ response_count = 0
80
+
81
+ with connect(self.ws_url, open_timeout=10, close_timeout=20) as websocket:
82
+ # Wait for setupComplete
83
+ setup_response = websocket.recv(timeout=10.0)
84
+ setup_data = json.loads(setup_response)
85
+ assert "setupComplete" in setup_data, (
86
+ f"Expected setupComplete, got {setup_data}"
87
+ )
88
+ logger.info("Received setupComplete")
89
+
90
+ # Send dummy audio chunk with user_id
91
+ dummy_audio = bytes([0] * 1024)
92
+ audio_msg = {
93
+ "user_id": "load-test-user",
94
+ "realtimeInput": {
95
+ "mediaChunks": [
96
+ {
97
+ "mimeType": "audio/pcm;rate=16000",
98
+ "data": dummy_audio.hex(),
99
+ }
100
+ ]
101
+ },
102
+ }
103
+ websocket.send(json.dumps(audio_msg))
104
+ logger.info("Sent audio chunk")
105
+
106
+ # Send text message to complete the turn
107
+ text_msg = {
108
+ "content": {
109
+ "role": "user",
110
+ "parts": [{"text": "Hello!"}],
111
+ }
112
+ }
113
+ websocket.send(json.dumps(text_msg))
114
+ logger.info("Sent text completion")
115
+
116
+ # Collect responses until turn_complete or timeout
117
+ for _ in range(20): # Max 20 responses
118
+ try:
119
+ response = websocket.recv(timeout=10.0)
120
+ response_data = json.loads(response)
121
+ response_count += 1
122
+ logger.debug(f"Received response: {response_data}")
123
+
124
+ if isinstance(response_data, dict) and response_data.get(
125
+ "turn_complete"
126
+ ):
127
+ logger.info(f"Turn complete after {response_count} responses")
128
+ break
129
+ except TimeoutError:
130
+ logger.info(f"Timeout after {response_count} responses")
131
+ break
132
+
133
+ return response_count
134
+
135
+
136
+ class RemoteAgentUser(WebSocketUser):
137
+ """User for testing remote agent engine deployment."""
138
+
139
+ # Set the host via command line: locust -f load_test.py --host=https://your-deployed-service.run.app
140
+ host = "http://localhost:8000" # Default for local testing
141
+ {%- else %}
142
+ {%- if cookiecutter.is_a2a %}
143
+
144
+ import json
145
+ import logging
146
+ import os
147
+ import time
148
+
149
+ from locust import HttpUser, between, task
150
+
151
+ # Configure logging
152
+ logging.basicConfig(
153
+ level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
154
+ )
155
+ logger = logging.getLogger(__name__)
156
+
157
+ # Initialize Vertex AI and load agent config
158
+ with open("deployment_metadata.json") as f:
159
+ remote_agent_engine_id = json.load(f)["remote_agent_engine_id"]
160
+
161
+ parts = remote_agent_engine_id.split("/")
162
+ project_id = parts[1]
163
+ location = parts[3]
164
+ engine_id = parts[5]
165
+
166
+ # Convert remote agent engine ID to URLs
167
+ base_url = f"https://{location}-aiplatform.googleapis.com"
168
+ a2a_base_path = f"/v1beta1/projects/{project_id}/locations/{location}/reasoningEngines/{engine_id}/a2a/v1"
169
+
170
+ logger.info("Using remote agent engine ID: %s", remote_agent_engine_id)
171
+ logger.info("Using base URL: %s", base_url)
172
+ logger.info("Using API base path: %s", a2a_base_path)
173
+
174
+
175
+ class SendMessageUser(HttpUser):
176
+ """Simulates a user interacting with the send message API."""
177
+
178
+ wait_time = between(1, 3) # Wait 1-3 seconds between tasks
179
+ host = base_url # Set the base host URL for Locust
180
+
181
+ @task
182
+ def send_message_and_poll(self) -> None:
183
+ """Simulates a chat interaction: sends a message and polls for completion."""
184
+ headers = {"Content-Type": "application/json"}
185
+ headers["Authorization"] = f"Bearer {os.environ['_AUTH_TOKEN']}"
186
+
187
+ data = {
188
+ "message": {
189
+ "messageId": "msg-id",
190
+ "content": [{"text": "Hello! What's the weather in New York?"}],
191
+ "role": "ROLE_USER",
192
+ }
193
+ }
194
+
195
+ e2e_start_time = time.time()
196
+ with self.client.post(
197
+ f"{a2a_base_path}/message:send",
198
+ headers=headers,
199
+ json=data,
200
+ catch_response=True,
201
+ name="/v1/message:send",
202
+ ) as response:
203
+ if response.status_code != 200:
204
+ response.failure(
205
+ f"Send failed with status code: {response.status_code}"
206
+ )
207
+ return
208
+
209
+ response.success()
210
+ response_data = response.json()
211
+
212
+ # Extract task ID
213
+ try:
214
+ task_id = response_data["task"]["id"]
215
+ except (KeyError, TypeError) as e:
216
+ logger.error(f"Failed to extract task ID: {e}")
217
+ return
218
+
219
+ # Poll for task completion
220
+ max_polls = 20 # Maximum number of poll attempts
221
+ poll_interval = 0.5 # Seconds between polls
222
+ poll_count = 0
223
+
224
+ while poll_count < max_polls:
225
+ poll_count += 1
226
+ time.sleep(poll_interval)
227
+
228
+ with self.client.get(
229
+ f"{a2a_base_path}/tasks/{task_id}",
230
+ headers=headers,
231
+ catch_response=True,
232
+ name="/v1/tasks/{id}",
233
+ ) as poll_response:
234
+ if poll_response.status_code != 200:
235
+ poll_response.failure(
236
+ f"Poll failed with status code: {poll_response.status_code}"
237
+ )
238
+ return
239
+
240
+ poll_data = poll_response.json()
241
+
242
+ try:
243
+ task_state = poll_data["status"]["state"]
244
+ except (KeyError, TypeError) as e:
245
+ logger.error(f"Failed to extract task state: {e}")
246
+ poll_response.failure(f"Invalid response format: {e}")
247
+ return
248
+
249
+ # Check if task is complete
250
+ if task_state in ["TASK_STATE_COMPLETED"]:
251
+ poll_response.success()
252
+
253
+ # Measure end-to-end time
254
+ e2e_duration = (time.time() - e2e_start_time) * 1000
255
+
256
+ # Fire custom event for end-to-end metrics
257
+ self.environment.events.request.fire(
258
+ request_type="E2E",
259
+ name="message:send_and_complete",
260
+ response_time=e2e_duration,
261
+ response_length=len(json.dumps(poll_data)),
262
+ response=poll_response,
263
+ context={"poll_count": poll_count},
264
+ )
265
+ return
266
+
267
+ elif task_state in ["TASK_STATE_WORKING"]:
268
+ poll_response.success()
269
+
270
+ else:
271
+ poll_response.failure(f"Task failed with state: {task_state}")
272
+ return
273
+
274
+ # Timeout - task didn't complete in time
275
+ self.environment.events.request.fire(
276
+ request_type="TIMEOUT",
277
+ name="message:timeout",
278
+ response_time=(time.time() - e2e_start_time) * 1000,
279
+ response_length=0,
280
+ response=None,
281
+ context={"poll_count": poll_count},
282
+ exception=TimeoutError(f"Task did not complete after {max_polls} polls"),
283
+ )
284
+ {%- else %}
285
+
286
+ import json
287
+ import logging
288
+ import os
289
+ import time
290
+
291
+ from locust import HttpUser, between, task
292
+
293
+ # Configure logging
294
+ logging.basicConfig(
295
+ level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
296
+ )
297
+ logger = logging.getLogger(__name__)
298
+
299
+ # Initialize Vertex AI and load agent config
300
+ with open("deployment_metadata.json") as f:
301
+ remote_agent_engine_id = json.load(f)["remote_agent_engine_id"]
302
+
303
+ parts = remote_agent_engine_id.split("/")
304
+ project_id = parts[1]
305
+ location = parts[3]
306
+ engine_id = parts[5]
307
+
308
+ # Convert remote agent engine ID to streaming URL.
309
+ base_url = f"https://{location}-aiplatform.googleapis.com"
310
+ url_path = f"/v1/projects/{project_id}/locations/{location}/reasoningEngines/{engine_id}:streamQuery"
311
+
312
+ logger.info("Using remote agent engine ID: %s", remote_agent_engine_id)
313
+ logger.info("Using base URL: %s", base_url)
314
+ logger.info("Using URL path: %s", url_path)
315
+
316
+
317
+ class ChatStreamUser(HttpUser):
318
+ """Simulates a user interacting with the chat stream API."""
319
+
320
+ wait_time = between(1, 3) # Wait 1-3 seconds between tasks
321
+ host = base_url # Set the base host URL for Locust
322
+
323
+ @task
324
+ def chat_stream(self) -> None:
325
+ """Simulates a chat stream interaction."""
326
+ headers = {"Content-Type": "application/json"}
327
+ headers["Authorization"] = f"Bearer {os.environ['_AUTH_TOKEN']}"
328
+ {% if cookiecutter.is_adk %}
329
+ data = {
330
+ "class_method": "async_stream_query",
331
+ "input": {
332
+ "user_id": "test",
333
+ "message": "What's the weather in San Francisco?",
334
+ },
335
+ }
336
+ {% else %}
337
+ data = {
338
+ "input": {
339
+ "input": {
340
+ "messages": [
341
+ {"type": "human", "content": "Hello, AI!"},
342
+ {"type": "ai", "content": "Hello!"},
343
+ {"type": "human", "content": "How are you?"},
344
+ ]
345
+ },
346
+ "config": {
347
+ "metadata": {"user_id": "test-user", "session_id": "test-session"}
348
+ },
349
+ }
350
+ }
351
+ {% endif %}
352
+ start_time = time.time()
353
+ with self.client.post(
354
+ url_path,
355
+ headers=headers,
356
+ json=data,
357
+ catch_response=True,
358
+ {%- if cookiecutter.is_adk %}
359
+ name="/streamQuery async_stream_query",
360
+ {%- else %}
361
+ name="/stream_messages first message",
362
+ {%- endif %}
363
+ stream=True,
364
+ params={"alt": "sse"},
365
+ ) as response:
366
+ if response.status_code == 200:
367
+ events = []
368
+ has_error = False
369
+ for line in response.iter_lines():
370
+ if line:
371
+ line_str = line.decode("utf-8")
372
+ events.append(line_str)
373
+
374
+ if "429 Too Many Requests" in line_str:
375
+ self.environment.events.request.fire(
376
+ request_type="POST",
377
+ name=f"{url_path} rate_limited 429s",
378
+ response_time=0,
379
+ response_length=len(line),
380
+ response=response,
381
+ context={},
382
+ )
383
+
384
+ # Check for error responses in the JSON payload
385
+ try:
386
+ event_data = json.loads(line_str)
387
+ if isinstance(event_data, dict) and "code" in event_data:
388
+ # Flag any non-2xx codes as errors
389
+ if event_data["code"] >= 400:
390
+ has_error = True
391
+ error_msg = event_data.get(
392
+ "message", "Unknown error"
393
+ )
394
+ response.failure(f"Error in response: {error_msg}")
395
+ logger.error(
396
+ "Received error response: code=%s, message=%s",
397
+ event_data["code"],
398
+ error_msg,
399
+ )
400
+ except json.JSONDecodeError:
401
+ # If it's not valid JSON, continue processing
402
+ pass
403
+
404
+ end_time = time.time()
405
+ total_time = end_time - start_time
406
+
407
+ # Only fire success event if no errors were found
408
+ if not has_error:
409
+ self.environment.events.request.fire(
410
+ request_type="POST",
411
+ {%- if cookiecutter.is_adk %}
412
+ name="/streamQuery end",
413
+ {%- else %}
414
+ name="/stream_messages end",
415
+ {%- endif %}
416
+ response_time=total_time * 1000, # Convert to milliseconds
417
+ response_length=len(events),
418
+ response=response,
419
+ context={},
420
+ )
421
+ else:
422
+ response.failure(f"Unexpected status code: {response.status_code}")
423
+ {%- endif %}
424
+ {%- endif %}
@@ -0,0 +1,138 @@
1
+ # Copyright 2025 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ # mypy: disable-error-code="arg-type"
16
+
17
+ """Helper functions for testing AgentEngineApp with A2A protocol."""
18
+
19
+ import asyncio
20
+ import json
21
+ from collections.abc import Awaitable, Callable
22
+ from typing import TYPE_CHECKING, Any
23
+
24
+ from starlette.requests import Request
25
+
26
+ if TYPE_CHECKING:
27
+ from {{cookiecutter.agent_directory}}.agent_engine_app import AgentEngineApp
28
+
29
+ # Test constants
30
+ POLL_MAX_ATTEMPTS = 30
31
+ POLL_INTERVAL_SECONDS = 1.0
32
+ TEST_ARTIFACTS_BUCKET = "test-artifacts-bucket"
33
+
34
+
35
+ def receive_wrapper(data: dict[str, Any] | None) -> Callable[[], Awaitable[dict]]:
36
+ """Creates a mock ASGI receive callable for testing.
37
+
38
+ Args:
39
+ data: Dictionary to encode as JSON request body
40
+
41
+ Returns:
42
+ Async callable that returns mock ASGI receive message
43
+ """
44
+
45
+ async def receive() -> dict:
46
+ byte_data = json.dumps(data).encode("utf-8")
47
+ return {"type": "http.request", "body": byte_data, "more_body": False}
48
+
49
+ return receive
50
+
51
+
52
+ def build_post_request(
53
+ data: dict[str, Any] | None = None, path_params: dict[str, str] | None = None
54
+ ) -> Request:
55
+ """Builds a mock Starlette Request object for a POST request with JSON data.
56
+
57
+ Args:
58
+ data: JSON data to include in request body
59
+ path_params: Path parameters to include in request scope
60
+
61
+ Returns:
62
+ Mock Starlette Request object
63
+ """
64
+ scope: dict[str, Any] = {
65
+ "type": "http",
66
+ "http_version": "1.1",
67
+ "headers": [(b"content-type", b"application/json")],
68
+ "app": None,
69
+ }
70
+ if path_params:
71
+ scope["path_params"] = path_params
72
+ receiver = receive_wrapper(data)
73
+ return Request(scope, receiver)
74
+
75
+
76
+ def build_get_request(path_params: dict[str, str] | None) -> Request:
77
+ """Builds a mock Starlette Request object for a GET request.
78
+
79
+ Args:
80
+ path_params: Path parameters to include in request scope
81
+
82
+ Returns:
83
+ Mock Starlette Request object
84
+ """
85
+ scope: dict[str, Any] = {
86
+ "type": "http",
87
+ "http_version": "1.1",
88
+ "query_string": b"",
89
+ "app": None,
90
+ }
91
+ if path_params:
92
+ scope["path_params"] = path_params
93
+
94
+ async def receive() -> dict:
95
+ return {"type": "http.disconnect"}
96
+
97
+ return Request(scope, receive)
98
+
99
+
100
+ async def poll_task_completion(
101
+ agent_app: "AgentEngineApp",
102
+ task_id: str,
103
+ max_attempts: int = POLL_MAX_ATTEMPTS,
104
+ interval: float = POLL_INTERVAL_SECONDS,
105
+ ) -> dict[str, Any]:
106
+ """Poll for task completion and return final response.
107
+
108
+ Args:
109
+ agent_app: The AgentEngineApp instance to poll
110
+ task_id: The task ID to poll for
111
+ max_attempts: Maximum number of polling attempts
112
+ interval: Seconds to wait between polls
113
+
114
+ Returns:
115
+ Final task response when completed
116
+
117
+ Raises:
118
+ AssertionError: If task fails or times out
119
+ """
120
+ for _ in range(max_attempts):
121
+ poll_request = build_get_request({"id": task_id})
122
+ response = await agent_app.on_get_task(
123
+ request=poll_request,
124
+ context=None,
125
+ )
126
+
127
+ task_state = response.get("status", {}).get("state", "")
128
+
129
+ if task_state == "TASK_STATE_COMPLETED":
130
+ return response
131
+ elif task_state == "TASK_STATE_FAILED":
132
+ raise AssertionError(f"Task failed: {response}")
133
+
134
+ await asyncio.sleep(interval)
135
+
136
+ raise AssertionError(
137
+ f"Task did not complete within {max_attempts * interval} seconds"
138
+ )