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,484 @@
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 asyncio
17
+ import json
18
+ import logging
19
+ import subprocess
20
+ import sys
21
+ import threading
22
+ import time
23
+ from collections.abc import Iterator
24
+ from typing import Any
25
+
26
+ import pytest
27
+ import requests
28
+ from websockets.asyncio.client import connect
29
+
30
+ # Configure logging
31
+ logging.basicConfig(level=logging.DEBUG)
32
+ logger = logging.getLogger(__name__)
33
+
34
+ WS_URL = "ws://127.0.0.1:8000/ws"
35
+ FEEDBACK_URL = "http://127.0.0.1:8000/feedback"
36
+
37
+
38
+ def log_output(pipe: Any, log_func: Any) -> None:
39
+ """Log the output from the given pipe."""
40
+ for line in iter(pipe.readline, ""):
41
+ log_func(line.strip())
42
+
43
+
44
+ def start_server() -> subprocess.Popen[str]:
45
+ """Start the server using expose_app in local mode."""
46
+ command = [
47
+ sys.executable,
48
+ "-m",
49
+ "uvicorn",
50
+ "app.app_utils.expose_app:app",
51
+ "--host",
52
+ "0.0.0.0",
53
+ "--port",
54
+ "8000",
55
+ ]
56
+ process = subprocess.Popen(
57
+ command,
58
+ stdout=subprocess.PIPE,
59
+ stderr=subprocess.PIPE,
60
+ text=True,
61
+ bufsize=1,
62
+ encoding="utf-8",
63
+ )
64
+
65
+ # Start threads to log stdout and stderr in real-time
66
+ threading.Thread(
67
+ target=log_output, args=(process.stdout, logger.info), daemon=True
68
+ ).start()
69
+ threading.Thread(
70
+ target=log_output, args=(process.stderr, logger.error), daemon=True
71
+ ).start()
72
+
73
+ return process
74
+
75
+
76
+ def wait_for_server(timeout: int = 60, interval: int = 1) -> bool:
77
+ """Wait for the server to be ready."""
78
+ start_time = time.time()
79
+ while time.time() - start_time < timeout:
80
+ try:
81
+ response = requests.get("http://127.0.0.1:8000/docs", timeout=10)
82
+ if response.status_code == 200:
83
+ logger.info("Server is ready")
84
+ return True
85
+ except Exception:
86
+ pass
87
+ time.sleep(interval)
88
+ logger.error(f"Server did not become ready within {timeout} seconds")
89
+ return False
90
+
91
+
92
+ @pytest.fixture(scope="module")
93
+ def server_fixture(request: Any) -> Iterator[subprocess.Popen[str]]:
94
+ """Pytest fixture to start and stop the server for testing."""
95
+ logger.info("Starting server process")
96
+ server_process = start_server()
97
+ if not wait_for_server():
98
+ pytest.fail("Server failed to start")
99
+ logger.info("Server process started")
100
+
101
+ def stop_server() -> None:
102
+ logger.info("Stopping server process")
103
+ server_process.terminate()
104
+ try:
105
+ server_process.wait(timeout=5)
106
+ except subprocess.TimeoutExpired:
107
+ logger.warning("Server process did not terminate, killing it")
108
+ server_process.kill()
109
+ server_process.wait()
110
+ logger.info("Server process stopped")
111
+
112
+ request.addfinalizer(stop_server)
113
+ yield server_process
114
+
115
+
116
+ @pytest.mark.asyncio
117
+ async def test_websocket_audio_input(server_fixture: subprocess.Popen[str]) -> None:
118
+ """Test websocket with audio input in local mode."""
119
+
120
+ async def send_message(websocket: Any, message: dict[str, Any]) -> None:
121
+ """Helper to send JSON messages."""
122
+ await websocket.send(json.dumps(message))
123
+
124
+ async def receive_message(websocket: Any, timeout: float = 5.0) -> dict[str, Any]:
125
+ """Helper to receive messages with timeout."""
126
+ try:
127
+ response = await asyncio.wait_for(websocket.recv(), timeout=timeout)
128
+ if isinstance(response, bytes):
129
+ return json.loads(response.decode())
130
+ if isinstance(response, str):
131
+ return json.loads(response)
132
+ return response
133
+ except asyncio.TimeoutError as exc:
134
+ raise TimeoutError(
135
+ f"No response received within {timeout} seconds"
136
+ ) from exc
137
+
138
+ try:
139
+ await asyncio.sleep(2)
140
+
141
+ async with connect(WS_URL, ping_timeout=10, close_timeout=10) as websocket:
142
+ try:
143
+ # Wait for setupComplete
144
+ setup_response = await receive_message(websocket, timeout=10.0)
145
+ assert "setupComplete" in setup_response
146
+ logger.info("Received setupComplete")
147
+
148
+ # Send dummy audio chunk with user_id
149
+ dummy_audio = bytes([0] * 1024)
150
+ audio_msg = {
151
+ "user_id": "test-user",
152
+ "realtimeInput": {
153
+ "mediaChunks": [
154
+ {
155
+ "mimeType": "audio/pcm;rate=16000",
156
+ "data": dummy_audio.hex(),
157
+ }
158
+ ]
159
+ },
160
+ }
161
+ await send_message(websocket, audio_msg)
162
+ logger.info("Sent audio chunk")
163
+
164
+ # Send text message to complete the turn (matching frontend format)
165
+ text_msg = {
166
+ "content": {
167
+ "role": "user",
168
+ "parts": [{"text": "Test audio"}],
169
+ }
170
+ }
171
+ await send_message(websocket, text_msg)
172
+ logger.info("Sent text completion")
173
+
174
+ # Collect responses
175
+ responses = []
176
+ for _ in range(10):
177
+ try:
178
+ response = await receive_message(websocket, timeout=5.0)
179
+ responses.append(response)
180
+ logger.info(f"Received: {response}")
181
+
182
+ if isinstance(response, dict) and response.get("turn_complete"):
183
+ break
184
+ except TimeoutError:
185
+ break
186
+
187
+ # Verify we got responses
188
+ assert len(responses) > 0, "No responses received"
189
+
190
+ logger.info(f"Audio test passed. Received {len(responses)} responses")
191
+
192
+ finally:
193
+ await websocket.close()
194
+
195
+ except Exception as e:
196
+ logger.error(f"Audio test failed: {e}")
197
+ raise
198
+
199
+
200
+ def test_feedback_endpoint(server_fixture: subprocess.Popen[str]) -> None:
201
+ """Test the feedback endpoint."""
202
+ feedback_data = {
203
+ "score": 5,
204
+ "text": "Great response!",
205
+ "user_id": "test-user-123",
206
+ "session_id": "test-session-123",
207
+ "log_type": "feedback",
208
+ }
209
+
210
+ response = requests.post(FEEDBACK_URL, json=feedback_data, timeout=10)
211
+ assert response.status_code == 200
212
+ assert response.json() == {"status": "success"}
213
+ logger.info("Feedback endpoint test passed")
214
+ {% else %}
215
+
216
+ # mypy: disable-error-code="arg-type"
217
+ {%- if cookiecutter.is_a2a %}
218
+
219
+ import os
220
+
221
+ import pytest
222
+
223
+ from {{cookiecutter.agent_directory}}.agent_engine_app import AgentEngineApp
224
+ from tests.helpers import (
225
+ build_get_request,
226
+ build_post_request,
227
+ poll_task_completion,
228
+ )
229
+ {%- elif cookiecutter.is_adk %}
230
+
231
+ import logging
232
+
233
+ import pytest
234
+ from google.adk.events.event import Event
235
+
236
+ from {{cookiecutter.agent_directory}}.agent_engine_app import AgentEngineApp
237
+ {%- else %}
238
+
239
+ import logging
240
+
241
+ import pytest
242
+
243
+ from {{cookiecutter.agent_directory}}.agent_engine_app import AgentEngineApp
244
+ {%- endif %}
245
+ {%- if cookiecutter.is_a2a %}
246
+
247
+
248
+ @pytest.fixture
249
+ def agent_app() -> AgentEngineApp:
250
+ """Fixture to create and set up AgentEngineApp instance"""
251
+ from {{cookiecutter.agent_directory}}.agent_engine_app import agent_engine
252
+
253
+ agent_engine.set_up()
254
+ return agent_engine
255
+ {%- else %}
256
+
257
+
258
+ @pytest.fixture
259
+ def agent_app() -> AgentEngineApp:
260
+ """Fixture to create and set up AgentEngineApp instance"""
261
+ from {{cookiecutter.agent_directory}}.agent_engine_app import agent_engine
262
+
263
+ agent_engine.set_up()
264
+ return agent_engine
265
+ {% endif %}
266
+ {%- if cookiecutter.is_a2a %}
267
+
268
+
269
+ @pytest.mark.asyncio
270
+ async def test_agent_on_message_send(agent_app: AgentEngineApp) -> None:
271
+ """Test complete A2A message workflow from send to task completion with artifacts."""
272
+ # Send message
273
+ message_data = {
274
+ "message": {
275
+ "messageId": f"msg-{os.urandom(8).hex()}",
276
+ "content": [{"text": "What is the capital of France?"}],
277
+ "role": "ROLE_USER",
278
+ },
279
+ }
280
+ response = await agent_app.on_message_send(
281
+ request=build_post_request(message_data),
282
+ context=None,
283
+ )
284
+
285
+ # Verify task creation
286
+ assert "task" in response and "id" in response["task"], (
287
+ "Expected task with ID in response"
288
+ )
289
+
290
+ # Poll for completion
291
+ final_response = await poll_task_completion(agent_app, response["task"]["id"])
292
+
293
+ # Verify artifacts
294
+ assert final_response.get("artifacts"), "Expected artifacts in completed task"
295
+ artifact = final_response["artifacts"][0]
296
+ assert artifact.get("parts") and artifact["parts"][0].get("text"), (
297
+ "Expected artifact with text content"
298
+ )
299
+
300
+
301
+ @pytest.mark.asyncio
302
+ async def test_agent_card(agent_app: AgentEngineApp) -> None:
303
+ """Test agent card retrieval and validation of required A2A fields."""
304
+ response = await agent_app.handle_authenticated_agent_card(
305
+ request=build_get_request(None),
306
+ context=None,
307
+ )
308
+
309
+ # Verify core agent card fields
310
+ assert response.get("name") == "root_agent", "Expected agent name 'root_agent'"
311
+ assert response.get("protocolVersion") == "0.3.0", "Expected protocol version 0.3.0"
312
+ assert response.get("preferredTransport") == "HTTP+JSON", (
313
+ "Expected HTTP+JSON transport"
314
+ )
315
+
316
+ # Verify capabilities
317
+ capabilities = response.get("capabilities", {})
318
+ assert capabilities.get("streaming") is False, "Expected streaming disabled"
319
+
320
+ # Verify skills
321
+ skills = response.get("skills", [])
322
+ assert len(skills) > 0, "Expected at least one skill"
323
+ for skill in skills:
324
+ assert all(key in skill for key in ["id", "name", "description"]), (
325
+ "Expected id, name, and description in each skill"
326
+ )
327
+
328
+ # Verify extended card support
329
+ assert response.get("supportsAuthenticatedExtendedCard") is True, (
330
+ "Expected supportsAuthenticatedExtendedCard to be True"
331
+ )
332
+ {% elif cookiecutter.is_adk %}
333
+
334
+ @pytest.mark.asyncio
335
+ async def test_agent_stream_query(agent_app: AgentEngineApp) -> None:
336
+ """
337
+ Integration test for the agent stream query functionality.
338
+ Tests that the agent returns valid streaming responses.
339
+ """
340
+ # Create message and events for the async_stream_query
341
+ message = "What's the weather in San Francisco?"
342
+ events = []
343
+ async for event in agent_app.async_stream_query(message=message, user_id="test"):
344
+ events.append(event)
345
+ assert len(events) > 0, "Expected at least one chunk in response"
346
+
347
+ # Check for valid content in the response
348
+ has_text_content = False
349
+ for event in events:
350
+ validated_event = Event.model_validate(event)
351
+ content = validated_event.content
352
+ if (
353
+ content is not None
354
+ and content.parts
355
+ and any(part.text for part in content.parts)
356
+ ):
357
+ has_text_content = True
358
+ break
359
+
360
+ assert has_text_content, "Expected at least one event with text content"
361
+
362
+
363
+ def test_agent_feedback(agent_app: AgentEngineApp) -> None:
364
+ """
365
+ Integration test for the agent feedback functionality.
366
+ Tests that feedback can be registered successfully.
367
+ """
368
+ feedback_data = {
369
+ "score": 5,
370
+ "text": "Great response!",
371
+ "user_id": "test-user-456",
372
+ "session_id": "test-session-456",
373
+ }
374
+
375
+ # Should not raise any exceptions
376
+ agent_app.register_feedback(feedback_data)
377
+
378
+ # Test invalid feedback
379
+ with pytest.raises(ValueError):
380
+ invalid_feedback = {
381
+ "score": "invalid", # Score must be numeric
382
+ "text": "Bad feedback",
383
+ "user_id": "test-user-789",
384
+ "session_id": "test-session-789",
385
+ }
386
+ agent_app.register_feedback(invalid_feedback)
387
+
388
+ logging.info("All assertions passed for agent feedback test")
389
+ {% else %}
390
+
391
+ def test_agent_stream_query(agent_app: AgentEngineApp) -> None:
392
+ """
393
+ Integration test for the agent stream query functionality.
394
+ Tests that the agent returns valid streaming responses.
395
+ """
396
+ input_dict = {
397
+ "messages": [
398
+ {"type": "human", "content": "Test message"},
399
+ ],
400
+ "user_id": "test-user",
401
+ "session_id": "test-session",
402
+ }
403
+
404
+ events = list(agent_app.stream_query(input=input_dict))
405
+
406
+ assert len(events) > 0, "Expected at least one chunk in response"
407
+
408
+ # Verify each event is a tuple of message and metadata
409
+ for event in events:
410
+ assert isinstance(event, list), "Event should be a list"
411
+ assert len(event) == 2, "Event should contain message and metadata"
412
+ message, _ = event
413
+
414
+ # Verify message structure
415
+ assert isinstance(message, dict), "Message should be a dictionary"
416
+ assert message["type"] == "constructor"
417
+ assert "kwargs" in message, "Constructor message should have kwargs"
418
+
419
+ # Verify at least one message has content
420
+ has_content = False
421
+ for event in events:
422
+ message = event[0]
423
+ if message.get("type") == "constructor" and "content" in message["kwargs"]:
424
+ has_content = True
425
+ break
426
+ assert has_content, "At least one message should have content"
427
+
428
+
429
+ def test_agent_query(agent_app: AgentEngineApp) -> None:
430
+ """
431
+ Integration test for the agent query functionality.
432
+ Tests that the agent returns valid responses.
433
+ """
434
+ input_dict = {
435
+ "messages": [
436
+ {"type": "human", "content": "Test message"},
437
+ ],
438
+ "user_id": "test-user",
439
+ "session_id": "test-session",
440
+ }
441
+
442
+ response = agent_app.query(input=input_dict)
443
+
444
+ # Basic response validation
445
+ assert isinstance(response, dict), "Response should be a dictionary"
446
+ assert "messages" in response, "Response should contain messages"
447
+ assert len(response["messages"]) > 0, "Response should have at least one message"
448
+
449
+ # Validate last message is AI response with content
450
+ message = response["messages"][-1]
451
+ kwargs = message["kwargs"]
452
+ assert kwargs["type"] == "ai", "Last message should be AI response"
453
+ assert len(kwargs["content"]) > 0, "AI message content should not be empty"
454
+
455
+ logging.info("All assertions passed for agent query test")
456
+
457
+
458
+ def test_agent_feedback(agent_app: AgentEngineApp) -> None:
459
+ """
460
+ Integration test for the agent feedback functionality.
461
+ Tests that feedback can be registered successfully.
462
+ """
463
+ feedback_data = {
464
+ "score": 5,
465
+ "text": "Great response!",
466
+ "user_id": "test-user-456",
467
+ "session_id": "test-session-456",
468
+ }
469
+
470
+ # Should not raise any exceptions
471
+ agent_app.register_feedback(feedback_data)
472
+
473
+ # Test invalid feedback
474
+ with pytest.raises(ValueError):
475
+ invalid_feedback = {
476
+ "score": "invalid", # Score must be numeric
477
+ "text": "Bad feedback",
478
+ "user_id": "test-user-789",
479
+ "session_id": "test-session-789",
480
+ }
481
+ agent_app.register_feedback(invalid_feedback)
482
+
483
+ logging.info("All assertions passed for agent feedback test")
484
+ {% endif %}{% endif %}
@@ -0,0 +1,84 @@
1
+ {%- if cookiecutter.agent_name == "adk_live" %}
2
+ # WebSocket Load Testing for Remote Agent Engine
3
+
4
+ This directory provides a comprehensive load testing framework for your Agent Engine application using WebSocket connections, leveraging the power of [Locust](http://locust.io), a leading open-source load testing tool.
5
+
6
+ The load test simulates realistic user interactions by:
7
+ - Establishing WebSocket connections
8
+ - Sending audio chunks in the proper `realtimeInput` format
9
+ - Sending text messages to complete turns
10
+ - Collecting and measuring responses until `turn_complete`
11
+
12
+ ## Load Testing with Remote Agent Engine
13
+
14
+ **1. Start the Expose App in Remote Mode:**
15
+
16
+ Launch the expose app server in a separate terminal, pointing to your deployed agent engine:
17
+
18
+ ```bash
19
+ uv run python -m app.app_utils.expose_app --mode remote --remote-id <your-agent-engine-id>
20
+ ```
21
+
22
+ Or if you have `deployment_metadata.json` in your project root:
23
+
24
+ ```bash
25
+ uv run python -m app.app_utils.expose_app --mode remote
26
+ ```
27
+
28
+ **2. Execute the Load Test:**
29
+
30
+ Using another terminal tab, trigger the Locust load test:
31
+
32
+ ```bash
33
+ uv run --with locust==2.31.1 --with websockets locust -f tests/load_test/load_test.py \
34
+ -H http://127.0.0.1:8000 \
35
+ --headless \
36
+ -t 30s -u 1 -r 1 \
37
+ --csv=tests/load_test/.results/results \
38
+ --html=tests/load_test/.results/report.html
39
+ ```
40
+
41
+ This command initiates a 30-second load test with 1 concurrent user.
42
+
43
+ **Results:**
44
+
45
+ Comprehensive CSV and HTML reports detailing the load test performance will be generated and saved in the `tests/load_test/.results` directory.
46
+ {%- else %}
47
+ # Robust Load Testing for Generative AI Applications
48
+
49
+ This directory provides a comprehensive load testing framework for your Generative AI application, leveraging the power of [Locust](http://locust.io), a leading open-source load testing tool.
50
+
51
+ ## Load Testing
52
+
53
+ Before running load tests, ensure you have deployed the backend remotely.
54
+
55
+ Follow these steps to execute load tests:
56
+
57
+ **1. Deploy the Backend Remotely:**
58
+ ```bash
59
+ gcloud config set project <your-dev-project-id>
60
+ make deploy
61
+ ```
62
+
63
+ **2. Create a Virtual Environment for Locust:**
64
+ It's recommended to use a separate terminal tab and create a virtual environment for Locust to avoid conflicts with your application's Python environment.
65
+
66
+ ```bash
67
+ python3 -m venv .locust_env && source .locust_env/bin/activate && pip install locust==2.31.1
68
+ ```
69
+
70
+ **3. Execute the Load Test:**
71
+ Trigger the Locust load test with the following command:
72
+
73
+ ```bash
74
+ export _AUTH_TOKEN=$(gcloud auth print-access-token -q)
75
+ locust -f tests/load_test/load_test.py \
76
+ --headless \
77
+ -t 30s -u 5 -r 2 \
78
+ --csv=tests/load_test/.results/results \
79
+ --html=tests/load_test/.results/report.html
80
+ ```
81
+
82
+ This command initiates a 30-second load test, simulating 2 users spawning per second, reaching a maximum of 10 concurrent users.
83
+ {%- endif %}
84
+