agent-starter-pack 0.15.7__py3-none-any.whl → 0.17.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.

Potentially problematic release.


This version of agent-starter-pack might be problematic. Click here for more details.

Files changed (195) hide show
  1. {agents → agent_starter_pack/agents}/adk_base/.template/templateconfig.yaml +1 -1
  2. {agents/live_api → agent_starter_pack/agents/adk_live}/.template/templateconfig.yaml +5 -7
  3. agent_starter_pack/agents/adk_live/README.md +32 -0
  4. agent_starter_pack/agents/adk_live/app/agent.py +48 -0
  5. agent_starter_pack/agents/adk_live/tests/unit/test_dummy.py +38 -0
  6. {agents → agent_starter_pack/agents}/agentic_rag/.template/templateconfig.yaml +1 -1
  7. agent_starter_pack/agents/crewai_coding_crew/app/agent.py +47 -0
  8. agent_starter_pack/agents/langgraph_base_react/app/agent.py +34 -0
  9. {src → agent_starter_pack}/base_template/GEMINI.md +1 -1
  10. {src → agent_starter_pack}/base_template/Makefile +130 -61
  11. {src → agent_starter_pack}/base_template/README.md +6 -6
  12. {src → agent_starter_pack}/base_template/deployment/terraform/dev/apis.tf +1 -1
  13. {src → agent_starter_pack}/base_template/deployment/terraform/dev/log_sinks.tf +31 -25
  14. {src → agent_starter_pack}/base_template/deployment/terraform/dev/providers.tf +1 -1
  15. {src → agent_starter_pack}/base_template/deployment/terraform/dev/variables.tf +1 -1
  16. {src → agent_starter_pack}/base_template/deployment/terraform/github.tf +14 -0
  17. {src → agent_starter_pack}/base_template/deployment/terraform/locals.tf +1 -1
  18. {src → agent_starter_pack}/base_template/deployment/terraform/log_sinks.tf +37 -28
  19. {src → agent_starter_pack}/base_template/deployment/terraform/providers.tf +1 -1
  20. {src → agent_starter_pack}/base_template/deployment/terraform/variables.tf +1 -1
  21. {src → agent_starter_pack}/base_template/deployment/terraform/{% if cookiecutter.cicd_runner == 'google_cloud_build' %}build_triggers.tf{% else %}unused_build_triggers.tf{% endif %} +4 -2
  22. {src → agent_starter_pack}/base_template/pyproject.toml +22 -21
  23. {src → agent_starter_pack}/base_template/{% if cookiecutter.cicd_runner == 'github_actions' %}.github{% else %}unused_github{% endif %}/workflows/deploy-to-prod.yaml +5 -5
  24. {src → agent_starter_pack}/base_template/{% if cookiecutter.cicd_runner == 'github_actions' %}.github{% else %}unused_github{% endif %}/workflows/pr_checks.yaml +3 -3
  25. {src → agent_starter_pack}/base_template/{% if cookiecutter.cicd_runner == 'github_actions' %}.github{% else %}unused_github{% endif %}/workflows/staging.yaml +74 -11
  26. {src → agent_starter_pack}/base_template/{% if cookiecutter.cicd_runner == 'google_cloud_build' %}.cloudbuild{% else %}unused_.cloudbuild{% endif %}/deploy-to-prod.yaml +6 -6
  27. {src → agent_starter_pack}/base_template/{% if cookiecutter.cicd_runner == 'google_cloud_build' %}.cloudbuild{% else %}unused_.cloudbuild{% endif %}/pr_checks.yaml +4 -4
  28. {src → agent_starter_pack}/base_template/{% if cookiecutter.cicd_runner == 'google_cloud_build' %}.cloudbuild{% else %}unused_.cloudbuild{% endif %}/staging.yaml +95 -13
  29. {src → agent_starter_pack}/base_template/{{cookiecutter.agent_directory}}/utils/tracing.py +1 -1
  30. {src → agent_starter_pack}/base_template/{{cookiecutter.agent_directory}}/utils/typing.py +4 -4
  31. {src → agent_starter_pack}/cli/commands/setup_cicd.py +1 -1
  32. {src → agent_starter_pack}/cli/main.py +2 -2
  33. {src → agent_starter_pack}/cli/utils/gcp.py +1 -1
  34. {src → agent_starter_pack}/cli/utils/remote_template.py +12 -9
  35. {src → agent_starter_pack}/cli/utils/template.py +19 -15
  36. agent_starter_pack/deployment_targets/agent_engine/deployment/terraform/{% if not cookiecutter.is_adk_live %}service.tf{% else %}unused_service.tf{% endif %} +82 -0
  37. agent_starter_pack/deployment_targets/agent_engine/tests/integration/test_agent_engine_app.py +387 -0
  38. agent_starter_pack/deployment_targets/agent_engine/tests/load_test/README.md +84 -0
  39. agent_starter_pack/deployment_targets/agent_engine/tests/load_test/load_test.py +255 -0
  40. {src → agent_starter_pack}/deployment_targets/agent_engine/{{cookiecutter.agent_directory}}/agent_engine_app.py +40 -14
  41. {src → agent_starter_pack}/deployment_targets/agent_engine/{{cookiecutter.agent_directory}}/utils/deployment.py +13 -4
  42. agent_starter_pack/deployment_targets/agent_engine/{{cookiecutter.agent_directory}}/utils/{% if cookiecutter.is_adk_live %}expose_app.py{% else %}unused_expose_app.py{% endif %} +520 -0
  43. {src → agent_starter_pack}/deployment_targets/cloud_run/Dockerfile +3 -3
  44. {src → agent_starter_pack}/deployment_targets/cloud_run/deployment/terraform/dev/service.tf +4 -4
  45. {src → agent_starter_pack}/deployment_targets/cloud_run/deployment/terraform/service.tf +7 -7
  46. {src → agent_starter_pack}/deployment_targets/cloud_run/tests/integration/test_server_e2e.py +207 -5
  47. {src → agent_starter_pack}/deployment_targets/cloud_run/tests/load_test/README.md +82 -0
  48. agent_starter_pack/deployment_targets/cloud_run/tests/load_test/load_test.py +249 -0
  49. {src → agent_starter_pack}/deployment_targets/cloud_run/{{cookiecutter.agent_directory}}/server.py +190 -146
  50. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/package-lock.json +39 -1007
  51. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/package.json +1 -9
  52. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/App.tsx +1 -1
  53. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/components/logger/Logger.tsx +8 -3
  54. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/components/logger/logger.scss +26 -0
  55. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/components/side-panel/SidePanel.tsx +11 -5
  56. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/components/side-panel/side-panel.scss +146 -115
  57. agent_starter_pack/frontends/adk_live_react/frontend/src/components/transcription-preview/TranscriptionPreview.tsx +106 -0
  58. agent_starter_pack/frontends/adk_live_react/frontend/src/components/transcription-preview/transcription-preview.scss +150 -0
  59. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/hooks/use-live-api.ts +8 -2
  60. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/multimodal-live-types.ts +38 -2
  61. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/utils/audio-recorder.ts +1 -1
  62. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/utils/audio-streamer.ts +1 -1
  63. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/utils/multimodal-live-client.ts +204 -23
  64. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/utils/utils.ts +27 -5
  65. {src → agent_starter_pack}/frontends/streamlit/frontend/utils/local_chat_history.py +2 -0
  66. {src → agent_starter_pack}/resources/docs/adk-cheatsheet.md +5 -5
  67. agent_starter_pack/resources/idx/.idx/dev.nix +64 -0
  68. agent_starter_pack/resources/idx/idx-template.json +6 -0
  69. {src → agent_starter_pack}/resources/idx/idx-template.nix +2 -3
  70. {src → agent_starter_pack}/resources/locks/uv-adk_base-agent_engine.lock +1079 -954
  71. {src → agent_starter_pack}/resources/locks/uv-adk_base-cloud_run.lock +1441 -1309
  72. agent_starter_pack/resources/locks/uv-adk_live-agent_engine.lock +4229 -0
  73. agent_starter_pack/resources/locks/uv-adk_live-cloud_run.lock +4822 -0
  74. {src → agent_starter_pack}/resources/locks/uv-agentic_rag-agent_engine.lock +1107 -997
  75. {src → agent_starter_pack}/resources/locks/uv-agentic_rag-cloud_run.lock +1485 -1368
  76. {src → agent_starter_pack}/resources/locks/uv-crewai_coding_crew-agent_engine.lock +1294 -1297
  77. {src → agent_starter_pack}/resources/locks/uv-crewai_coding_crew-cloud_run.lock +2028 -1807
  78. {src → agent_starter_pack}/resources/locks/uv-langgraph_base_react-agent_engine.lock +1176 -1197
  79. {src → agent_starter_pack}/resources/locks/uv-langgraph_base_react-cloud_run.lock +1947 -1679
  80. {src → agent_starter_pack}/utils/generate_locks.py +12 -7
  81. {src → agent_starter_pack}/utils/lock_utils.py +2 -2
  82. {src → agent_starter_pack}/utils/watch_and_rebuild.py +1 -1
  83. {agent_starter_pack-0.15.7.dist-info → agent_starter_pack-0.17.0.dist-info}/METADATA +17 -18
  84. agent_starter_pack-0.17.0.dist-info/RECORD +179 -0
  85. agent_starter_pack-0.17.0.dist-info/entry_points.txt +2 -0
  86. llm.txt +1 -1
  87. agent_starter_pack-0.15.7.dist-info/RECORD +0 -176
  88. agent_starter_pack-0.15.7.dist-info/entry_points.txt +0 -2
  89. agents/crewai_coding_crew/app/agent.py +0 -86
  90. agents/langgraph_base_react/app/agent.py +0 -73
  91. agents/live_api/README.md +0 -37
  92. agents/live_api/app/agent.py +0 -72
  93. agents/live_api/tests/integration/test_server_e2e.py +0 -260
  94. agents/live_api/tests/load_test/load_test.py +0 -40
  95. agents/live_api/tests/unit/test_server.py +0 -144
  96. src/deployment_targets/agent_engine/tests/integration/test_agent_engine_app.py +0 -186
  97. src/deployment_targets/agent_engine/tests/load_test/README.md +0 -37
  98. src/deployment_targets/agent_engine/tests/load_test/load_test.py +0 -126
  99. src/deployment_targets/cloud_run/tests/load_test/load_test.py +0 -122
  100. src/resources/idx/.idx/dev.nix +0 -50
  101. src/resources/idx/idx-template.json +0 -21
  102. src/resources/locks/uv-live_api-cloud_run.lock +0 -6118
  103. {agents → agent_starter_pack/agents}/README.md +0 -0
  104. {agents → agent_starter_pack/agents}/adk_base/README.md +0 -0
  105. {agents → agent_starter_pack/agents}/adk_base/app/__init__.py +0 -0
  106. {agents → agent_starter_pack/agents}/adk_base/app/agent.py +0 -0
  107. {agents → agent_starter_pack/agents}/adk_base/notebooks/adk_app_testing.ipynb +0 -0
  108. {agents → agent_starter_pack/agents}/adk_base/notebooks/evaluating_adk_agent.ipynb +0 -0
  109. {agents → agent_starter_pack/agents}/adk_base/tests/integration/test_agent.py +0 -0
  110. {agents → agent_starter_pack/agents}/agentic_rag/README.md +0 -0
  111. {agents → agent_starter_pack/agents}/agentic_rag/app/__init__.py +0 -0
  112. {agents → agent_starter_pack/agents}/agentic_rag/app/agent.py +0 -0
  113. {agents → agent_starter_pack/agents}/agentic_rag/app/retrievers.py +0 -0
  114. {agents → agent_starter_pack/agents}/agentic_rag/app/templates.py +0 -0
  115. {agents → agent_starter_pack/agents}/agentic_rag/notebooks/adk_app_testing.ipynb +0 -0
  116. {agents → agent_starter_pack/agents}/agentic_rag/notebooks/evaluating_adk_agent.ipynb +0 -0
  117. {agents → agent_starter_pack/agents}/agentic_rag/tests/integration/test_agent.py +0 -0
  118. {agents → agent_starter_pack/agents}/crewai_coding_crew/.template/templateconfig.yaml +0 -0
  119. {agents → agent_starter_pack/agents}/crewai_coding_crew/README.md +0 -0
  120. {agents → agent_starter_pack/agents}/crewai_coding_crew/app/crew/config/agents.yaml +0 -0
  121. {agents → agent_starter_pack/agents}/crewai_coding_crew/app/crew/config/tasks.yaml +0 -0
  122. {agents → agent_starter_pack/agents}/crewai_coding_crew/app/crew/crew.py +0 -0
  123. {agents → agent_starter_pack/agents}/crewai_coding_crew/notebooks/evaluating_crewai_agent.ipynb +0 -0
  124. {agents → agent_starter_pack/agents}/crewai_coding_crew/notebooks/evaluating_langgraph_agent.ipynb +0 -0
  125. {agents → agent_starter_pack/agents}/crewai_coding_crew/tests/integration/test_agent.py +0 -0
  126. {agents → agent_starter_pack/agents}/langgraph_base_react/.template/templateconfig.yaml +0 -0
  127. {agents → agent_starter_pack/agents}/langgraph_base_react/README.md +0 -0
  128. {agents → agent_starter_pack/agents}/langgraph_base_react/notebooks/evaluating_langgraph_agent.ipynb +0 -0
  129. {agents → agent_starter_pack/agents}/langgraph_base_react/tests/integration/test_agent.py +0 -0
  130. {src → agent_starter_pack}/base_template/.gitignore +0 -0
  131. {src → agent_starter_pack}/base_template/deployment/README.md +0 -0
  132. {src → agent_starter_pack}/base_template/deployment/terraform/apis.tf +0 -0
  133. {src → agent_starter_pack}/base_template/deployment/terraform/dev/iam.tf +0 -0
  134. {src → agent_starter_pack}/base_template/deployment/terraform/dev/storage.tf +0 -0
  135. {src → agent_starter_pack}/base_template/deployment/terraform/dev/vars/env.tfvars +0 -0
  136. {src → agent_starter_pack}/base_template/deployment/terraform/iam.tf +0 -0
  137. {src → agent_starter_pack}/base_template/deployment/terraform/service_accounts.tf +0 -0
  138. {src → agent_starter_pack}/base_template/deployment/terraform/storage.tf +0 -0
  139. {src → agent_starter_pack}/base_template/deployment/terraform/vars/env.tfvars +0 -0
  140. {src → agent_starter_pack}/base_template/deployment/terraform/{% if cookiecutter.cicd_runner == 'github_actions' %}wif.tf{% else %}unused_wif.tf{% endif %} +0 -0
  141. {src → agent_starter_pack}/base_template/tests/unit/test_dummy.py +0 -0
  142. {src → agent_starter_pack}/base_template/{{cookiecutter.agent_directory}}/utils/gcs.py +0 -0
  143. {src → agent_starter_pack}/cli/commands/create.py +0 -0
  144. {src → agent_starter_pack}/cli/commands/enhance.py +0 -0
  145. {src → agent_starter_pack}/cli/commands/list.py +0 -0
  146. {src → agent_starter_pack}/cli/utils/__init__.py +0 -0
  147. {src → agent_starter_pack}/cli/utils/cicd.py +0 -0
  148. {src → agent_starter_pack}/cli/utils/datastores.py +0 -0
  149. {src → agent_starter_pack}/cli/utils/logging.py +0 -0
  150. {src → agent_starter_pack}/cli/utils/version.py +0 -0
  151. {src → agent_starter_pack}/data_ingestion/README.md +0 -0
  152. {src → agent_starter_pack}/data_ingestion/data_ingestion_pipeline/components/ingest_data.py +0 -0
  153. {src → agent_starter_pack}/data_ingestion/data_ingestion_pipeline/components/process_data.py +0 -0
  154. {src → agent_starter_pack}/data_ingestion/data_ingestion_pipeline/pipeline.py +0 -0
  155. {src → agent_starter_pack}/data_ingestion/data_ingestion_pipeline/submit_pipeline.py +0 -0
  156. {src → agent_starter_pack}/data_ingestion/pyproject.toml +0 -0
  157. {src → agent_starter_pack}/data_ingestion/uv.lock +0 -0
  158. {src → agent_starter_pack}/deployment_targets/agent_engine/deployment_metadata.json +0 -0
  159. {src → agent_starter_pack}/deployment_targets/agent_engine/notebooks/intro_agent_engine.ipynb +0 -0
  160. {src → agent_starter_pack}/deployment_targets/agent_engine/tests/load_test/.results/.placeholder +0 -0
  161. {src → agent_starter_pack}/deployment_targets/cloud_run/tests/load_test/.results/.placeholder +0 -0
  162. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/public/favicon.ico +0 -0
  163. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/public/index.html +0 -0
  164. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/public/robots.txt +0 -0
  165. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/App.scss +0 -0
  166. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/App.test.tsx +0 -0
  167. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/components/audio-pulse/AudioPulse.tsx +0 -0
  168. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/components/audio-pulse/audio-pulse.scss +0 -0
  169. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/components/logger/mock-logs.ts +0 -0
  170. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/contexts/LiveAPIContext.tsx +0 -0
  171. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/hooks/use-media-stream-mux.ts +0 -0
  172. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/hooks/use-screen-capture.ts +0 -0
  173. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/hooks/use-webcam.ts +0 -0
  174. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/index.css +0 -0
  175. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/index.tsx +0 -0
  176. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/react-app-env.d.ts +0 -0
  177. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/reportWebVitals.ts +0 -0
  178. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/setupTests.ts +0 -0
  179. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/utils/audioworklet-registry.ts +0 -0
  180. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/utils/store-logger.ts +0 -0
  181. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/utils/worklets/audio-processing.ts +0 -0
  182. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/src/utils/worklets/vol-meter.ts +0 -0
  183. {src/frontends/live_api_react → agent_starter_pack/frontends/adk_live_react}/frontend/tsconfig.json +0 -0
  184. {src → agent_starter_pack}/frontends/streamlit/frontend/side_bar.py +0 -0
  185. {src → agent_starter_pack}/frontends/streamlit/frontend/streamlit_app.py +0 -0
  186. {src → agent_starter_pack}/frontends/streamlit/frontend/style/app_markdown.py +0 -0
  187. {src → agent_starter_pack}/frontends/streamlit/frontend/utils/chat_utils.py +0 -0
  188. {src → agent_starter_pack}/frontends/streamlit/frontend/utils/message_editing.py +0 -0
  189. {src → agent_starter_pack}/frontends/streamlit/frontend/utils/multimodal_utils.py +0 -0
  190. {src → agent_starter_pack}/frontends/streamlit/frontend/utils/stream_handler.py +0 -0
  191. {src → agent_starter_pack}/frontends/streamlit/frontend/utils/title_summary.py +0 -0
  192. {src → agent_starter_pack}/resources/containers/data_processing/Dockerfile +0 -0
  193. {src → agent_starter_pack}/resources/containers/e2e-tests/Dockerfile +0 -0
  194. {agent_starter_pack-0.15.7.dist-info → agent_starter_pack-0.17.0.dist-info}/WHEEL +0 -0
  195. {agent_starter_pack-0.15.7.dist-info → agent_starter_pack-0.17.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,255 @@
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
+
143
+ import json
144
+ import logging
145
+ import os
146
+ import time
147
+
148
+ from locust import HttpUser, between, task
149
+
150
+ # Configure logging
151
+ logging.basicConfig(
152
+ level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
153
+ )
154
+ logger = logging.getLogger(__name__)
155
+
156
+ # Initialize Vertex AI and load agent config
157
+ with open("deployment_metadata.json") as f:
158
+ remote_agent_engine_id = json.load(f)["remote_agent_engine_id"]
159
+
160
+ parts = remote_agent_engine_id.split("/")
161
+ project_id = parts[1]
162
+ location = parts[3]
163
+ engine_id = parts[5]
164
+
165
+ # Convert remote agent engine ID to streaming URL.
166
+ base_url = f"https://{location}-aiplatform.googleapis.com"
167
+ url_path = f"/v1/projects/{project_id}/locations/{location}/reasoningEngines/{engine_id}:streamQuery"
168
+
169
+ logger.info("Using remote agent engine ID: %s", remote_agent_engine_id)
170
+ logger.info("Using base URL: %s", base_url)
171
+ logger.info("Using URL path: %s", url_path)
172
+
173
+
174
+ class ChatStreamUser(HttpUser):
175
+ """Simulates a user interacting with the chat stream API."""
176
+
177
+ wait_time = between(1, 3) # Wait 1-3 seconds between tasks
178
+ host = base_url # Set the base host URL for Locust
179
+
180
+ @task
181
+ def chat_stream(self) -> None:
182
+ """Simulates a chat stream interaction."""
183
+ headers = {"Content-Type": "application/json"}
184
+ headers["Authorization"] = f"Bearer {os.environ['_AUTH_TOKEN']}"
185
+ {% if cookiecutter.is_adk %}
186
+ data = {
187
+ "class_method": "async_stream_query",
188
+ "input": {
189
+ "user_id": "test",
190
+ "message": "What's the weather in San Francisco?",
191
+ },
192
+ }
193
+ {% else %}
194
+ data = {
195
+ "input": {
196
+ "input": {
197
+ "messages": [
198
+ {"type": "human", "content": "Hello, AI!"},
199
+ {"type": "ai", "content": "Hello!"},
200
+ {"type": "human", "content": "How are you?"},
201
+ ]
202
+ },
203
+ "config": {
204
+ "metadata": {"user_id": "test-user", "session_id": "test-session"}
205
+ },
206
+ }
207
+ }
208
+ {% endif %}
209
+ start_time = time.time()
210
+ with self.client.post(
211
+ url_path,
212
+ headers=headers,
213
+ json=data,
214
+ catch_response=True,
215
+ {%- if cookiecutter.is_adk %}
216
+ name="/streamQuery async_stream_query",
217
+ {%- else %}
218
+ name="/stream_messages first message",
219
+ {%- endif %}
220
+ stream=True,
221
+ params={"alt": "sse"},
222
+ ) as response:
223
+ if response.status_code == 200:
224
+ events = []
225
+ for line in response.iter_lines():
226
+ if line:
227
+ line_str = line.decode("utf-8")
228
+ events.append(line_str)
229
+
230
+ if "429 Too Many Requests" in line_str:
231
+ self.environment.events.request.fire(
232
+ request_type="POST",
233
+ name=f"{url_path} rate_limited 429s",
234
+ response_time=0,
235
+ response_length=len(line),
236
+ response=response,
237
+ context={},
238
+ )
239
+ end_time = time.time()
240
+ total_time = end_time - start_time
241
+ self.environment.events.request.fire(
242
+ request_type="POST",
243
+ {%- if cookiecutter.is_adk %}
244
+ name="/streamQuery end",
245
+ {%- else %}
246
+ name="/stream_messages end",
247
+ {%- endif %}
248
+ response_time=total_time * 1000, # Convert to milliseconds
249
+ response_length=len(events),
250
+ response=response,
251
+ context={},
252
+ )
253
+ else:
254
+ response.failure(f"Unexpected status code: {response.status_code}")
255
+ {%- endif %}
@@ -13,7 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
  # mypy: disable-error-code="attr-defined,arg-type"
16
- {%- if "adk" in cookiecutter.tags %}
16
+ {%- if cookiecutter.is_adk %}
17
17
  import logging
18
18
  import os
19
19
  from typing import Any
@@ -25,8 +25,12 @@ from google.adk.artifacts import GcsArtifactService
25
25
  from google.cloud import logging as google_cloud_logging
26
26
  from opentelemetry import trace
27
27
  from opentelemetry.sdk.trace import TracerProvider, export
28
- from vertexai._genai.types import AgentEngine, AgentEngineConfig
28
+ from vertexai._genai.types import AgentEngine, AgentEngineConfig{%- if cookiecutter.is_adk_live %}, AgentServerMode{%- endif %}
29
+ {%- if cookiecutter.is_adk_live %}
30
+ from vertexai.preview.reasoning_engines import AdkApp
31
+ {%- else %}
29
32
  from vertexai.agent_engines.templates.adk import AdkApp
33
+ {%- endif %}
30
34
 
31
35
  from {{cookiecutter.agent_directory}}.agent import root_agent
32
36
  from {{cookiecutter.agent_directory}}.utils.deployment import (
@@ -235,6 +239,16 @@ class AgentEngineApp:
235
239
  default=None,
236
240
  help="Service account email to use for the agent engine",
237
241
  )
242
+ @click.option(
243
+ "--staging-bucket-uri",
244
+ default=None,
245
+ help="GCS bucket URI for staging files (defaults to gs://{project}-agent-engine)",
246
+ )
247
+ @click.option(
248
+ "--artifacts-bucket-name",
249
+ default=None,
250
+ help="GCS bucket name for artifacts (defaults to gs://{project}-agent-engine)",
251
+ )
238
252
  def deploy_agent_engine_app(
239
253
  project: str | None,
240
254
  location: str,
@@ -243,13 +257,31 @@ def deploy_agent_engine_app(
243
257
  extra_packages: tuple[str, ...],
244
258
  set_env_vars: str | None,
245
259
  service_account: str | None,
260
+ staging_bucket_uri: str | None,
261
+ artifacts_bucket_name: str | None,
246
262
  ) -> AgentEngine:
247
263
  """Deploy the agent engine app to Vertex AI."""
264
+
265
+ logging.basicConfig(level=logging.INFO)
266
+
248
267
  # Parse environment variables if provided
249
268
  env_vars = parse_env_vars(set_env_vars)
250
269
 
251
270
  if not project:
252
271
  _, project = google.auth.default()
272
+ if not staging_bucket_uri:
273
+ staging_bucket_uri = f"gs://{project}-agent-engine"
274
+ if not artifacts_bucket_name:
275
+ artifacts_bucket_name = f"gs://{project}-agent-engine"
276
+
277
+ {%- if "adk" in cookiecutter.tags %}
278
+ create_bucket_if_not_exists(
279
+ bucket_name=artifacts_bucket_name, project=project, location=location
280
+ )
281
+ {%- endif %}
282
+ create_bucket_if_not_exists(
283
+ bucket_name=staging_bucket_uri, project=project, location=location
284
+ )
253
285
 
254
286
  print("""
255
287
  ╔═══════════════════════════════════════════════════════════╗
@@ -259,18 +291,7 @@ def deploy_agent_engine_app(
259
291
  ╚═══════════════════════════════════════════════════════════╝
260
292
  """)
261
293
 
262
- logging.basicConfig(level=logging.INFO)
263
294
  extra_packages_list = list(extra_packages)
264
- staging_bucket_uri = f"gs://{project}-agent-engine"
265
- {%- if "adk" in cookiecutter.tags %}
266
- artifacts_bucket_name = f"{project}-{{cookiecutter.project_name}}-logs"
267
- create_bucket_if_not_exists(
268
- bucket_name=artifacts_bucket_name, project=project, location=location
269
- )
270
- {%- endif %}
271
- create_bucket_if_not_exists(
272
- bucket_name=staging_bucket_uri, project=project, location=location
273
- )
274
295
 
275
296
  # Initialize vertexai client
276
297
  client = vertexai.Client(
@@ -282,7 +303,7 @@ def deploy_agent_engine_app(
282
303
  # Read requirements
283
304
  with open(requirements_file) as f:
284
305
  requirements = f.read().strip().split("\n")
285
- {% if "adk" in cookiecutter.tags %}
306
+ {% if cookiecutter.is_adk %}
286
307
  agent_engine = AgentEngineApp(
287
308
  agent=root_agent,
288
309
  artifact_service_builder=lambda: GcsArtifactService(
@@ -314,6 +335,11 @@ def deploy_agent_engine_app(
314
335
  requirements=requirements,
315
336
  staging_bucket=staging_bucket_uri,
316
337
  labels=labels,
338
+ gcs_dir_name=agent_name,
339
+ {%- if cookiecutter.is_adk_live %}
340
+ agent_server_mode=AgentServerMode.EXPERIMENTAL, # Enable bidi streaming
341
+ resource_limits={"cpu": "4", "memory": "8Gi"},
342
+ {%- endif %}
317
343
  )
318
344
 
319
345
  agent_config = {
@@ -75,11 +75,20 @@ def print_deployment_success(
75
75
  agent_engine_id = remote_agent.api_resource.name.split("/")[-1]
76
76
  console_url = f"https://console.cloud.google.com/vertex-ai/agents/locations/{location}/agent-engines/{agent_engine_id}?project={project}"
77
77
 
78
- {%- if "adk" in cookiecutter.tags %}
78
+ {%- if cookiecutter.is_adk %}
79
+ {%- if cookiecutter.is_adk_live %}
80
+ print("\n✅ Deployment successful! Run your agent with: `make playground-remote`")
81
+ {%- else %}
79
82
  print(
80
- f"\n✅ Deployment successful! Test your agent: notebooks/adk_app_testing.ipynb"
81
- f"\n📊 View in console: {console_url}\n"
83
+ "\n✅ Deployment successful! Test your agent: notebooks/adk_app_testing.ipynb"
82
84
  )
85
+ {%- endif %}
86
+ service_account = remote_agent.api_resource.spec.service_account
87
+ print(f"Service Account: {service_account}")
88
+ print(f"\n📊 View in console: {console_url}\n")
83
89
  {%- else %}
84
- print(f"\n✅ Deployment successful!\n📊 View in console: {console_url}\n")
90
+ print("\n✅ Deployment successful!")
91
+ service_account = remote_agent.api_resource.spec.service_account
92
+ print(f"Service Account: {service_account}")
93
+ print(f"\n📊 View in console: {console_url}\n")
85
94
  {%- endif %}