agent-starter-pack 0.5.2__py3-none-any.whl → 0.6.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 (75) hide show
  1. {agent_starter_pack-0.5.2.dist-info → agent_starter_pack-0.6.0.dist-info}/METADATA +2 -2
  2. {agent_starter_pack-0.5.2.dist-info → agent_starter_pack-0.6.0.dist-info}/RECORD +66 -40
  3. agents/adk_base/notebooks/adk_app_testing.ipynb +1 -1
  4. agents/adk_base/template/.templateconfig.yaml +1 -1
  5. agents/adk_gemini_fullstack/README.md +148 -0
  6. agents/adk_gemini_fullstack/app/agent.py +349 -0
  7. agents/adk_gemini_fullstack/app/config.py +11 -0
  8. agents/adk_gemini_fullstack/notebooks/adk_app_testing.ipynb +353 -0
  9. agents/adk_gemini_fullstack/notebooks/evaluating_adk_agent.ipynb +1528 -0
  10. agents/adk_gemini_fullstack/template/.templateconfig.yaml +37 -0
  11. agents/adk_gemini_fullstack/tests/integration/test_agent.py +58 -0
  12. agents/agentic_rag/notebooks/adk_app_testing.ipynb +1 -1
  13. agents/agentic_rag/template/.templateconfig.yaml +1 -1
  14. agents/crewai_coding_crew/template/.templateconfig.yaml +1 -1
  15. agents/langgraph_base_react/template/.templateconfig.yaml +1 -1
  16. src/base_template/Makefile +21 -2
  17. src/base_template/README.md +8 -3
  18. src/base_template/pyproject.toml +1 -4
  19. src/cli/commands/create.py +17 -10
  20. src/cli/utils/template.py +13 -10
  21. src/data_ingestion/data_ingestion_pipeline/components/process_data.py +1 -1
  22. src/deployment_targets/agent_engine/app/agent_engine_app.py +17 -5
  23. src/deployment_targets/cloud_run/app/server.py +17 -2
  24. src/deployment_targets/cloud_run/tests/integration/test_server_e2e.py +1 -1
  25. src/deployment_targets/cloud_run/tests/load_test/.results/.placeholder +321 -0
  26. src/frontends/adk_gemini_fullstack/frontend/components.json +21 -0
  27. src/frontends/adk_gemini_fullstack/frontend/eslint.config.js +28 -0
  28. src/frontends/adk_gemini_fullstack/frontend/index.html +12 -0
  29. src/frontends/adk_gemini_fullstack/frontend/package-lock.json +5829 -0
  30. src/frontends/adk_gemini_fullstack/frontend/package.json +46 -0
  31. src/frontends/adk_gemini_fullstack/frontend/public/vite.svg +1 -0
  32. src/frontends/adk_gemini_fullstack/frontend/src/App.tsx +565 -0
  33. src/frontends/adk_gemini_fullstack/frontend/src/components/ActivityTimeline.tsx +244 -0
  34. src/frontends/adk_gemini_fullstack/frontend/src/components/ChatMessagesView.tsx +419 -0
  35. src/frontends/adk_gemini_fullstack/frontend/src/components/InputForm.tsx +60 -0
  36. src/frontends/adk_gemini_fullstack/frontend/src/components/WelcomeScreen.tsx +56 -0
  37. src/frontends/adk_gemini_fullstack/frontend/src/components/ui/badge.tsx +46 -0
  38. src/frontends/adk_gemini_fullstack/frontend/src/components/ui/button.tsx +59 -0
  39. src/frontends/adk_gemini_fullstack/frontend/src/components/ui/card.tsx +92 -0
  40. src/frontends/adk_gemini_fullstack/frontend/src/components/ui/input.tsx +21 -0
  41. src/frontends/adk_gemini_fullstack/frontend/src/components/ui/scroll-area.tsx +56 -0
  42. src/frontends/adk_gemini_fullstack/frontend/src/components/ui/select.tsx +183 -0
  43. src/frontends/adk_gemini_fullstack/frontend/src/components/ui/tabs.tsx +64 -0
  44. src/frontends/adk_gemini_fullstack/frontend/src/components/ui/textarea.tsx +18 -0
  45. src/frontends/adk_gemini_fullstack/frontend/src/global.css +154 -0
  46. src/frontends/adk_gemini_fullstack/frontend/src/main.tsx +13 -0
  47. src/frontends/adk_gemini_fullstack/frontend/src/utils.ts +7 -0
  48. src/frontends/adk_gemini_fullstack/frontend/src/vite-env.d.ts +1 -0
  49. src/frontends/adk_gemini_fullstack/frontend/tsconfig.json +28 -0
  50. src/frontends/adk_gemini_fullstack/frontend/tsconfig.node.json +24 -0
  51. src/frontends/adk_gemini_fullstack/frontend/vite.config.ts +26 -0
  52. src/resources/locks/uv-adk_base-agent_engine.lock +303 -251
  53. src/resources/locks/uv-adk_base-cloud_run.lock +367 -306
  54. src/resources/locks/uv-adk_gemini_fullstack-agent_engine.lock +3217 -0
  55. src/resources/locks/uv-adk_gemini_fullstack-cloud_run.lock +3513 -0
  56. src/resources/locks/uv-agentic_rag-agent_engine.lock +621 -565
  57. src/resources/locks/uv-agentic_rag-cloud_run.lock +854 -782
  58. src/resources/locks/uv-crewai_coding_crew-agent_engine.lock +860 -723
  59. src/resources/locks/uv-crewai_coding_crew-cloud_run.lock +1139 -960
  60. src/resources/locks/uv-langgraph_base_react-agent_engine.lock +718 -587
  61. src/resources/locks/uv-langgraph_base_react-cloud_run.lock +977 -815
  62. src/resources/locks/uv-live_api-cloud_run.lock +784 -709
  63. src/frontends/streamlit_adk/frontend/side_bar.py +0 -214
  64. src/frontends/streamlit_adk/frontend/streamlit_app.py +0 -314
  65. src/frontends/streamlit_adk/frontend/style/app_markdown.py +0 -37
  66. src/frontends/streamlit_adk/frontend/utils/chat_utils.py +0 -84
  67. src/frontends/streamlit_adk/frontend/utils/local_chat_history.py +0 -110
  68. src/frontends/streamlit_adk/frontend/utils/message_editing.py +0 -61
  69. src/frontends/streamlit_adk/frontend/utils/multimodal_utils.py +0 -223
  70. src/frontends/streamlit_adk/frontend/utils/stream_handler.py +0 -311
  71. src/frontends/streamlit_adk/frontend/utils/title_summary.py +0 -129
  72. {agent_starter_pack-0.5.2.dist-info → agent_starter_pack-0.6.0.dist-info}/WHEEL +0 -0
  73. {agent_starter_pack-0.5.2.dist-info → agent_starter_pack-0.6.0.dist-info}/entry_points.txt +0 -0
  74. {agent_starter_pack-0.5.2.dist-info → agent_starter_pack-0.6.0.dist-info}/licenses/LICENSE +0 -0
  75. /src/{deployment_targets/agent_engine → base_template}/app/utils/gcs.py +0 -0
@@ -0,0 +1,37 @@
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
+ description: "A production-ready fullstack research agent that uses Gemini to strategize, research, and synthesize comprehensive reports with human-in-the-loop collaboration"
16
+ example_question: "A report on the latest Google I/O event"
17
+ settings:
18
+ requires_data_ingestion: false
19
+ deployment_targets: ["agent_engine", "cloud_run"]
20
+ extra_dependencies: ["google-adk~=1.3.0"]
21
+ tags: ["adk"]
22
+ frontend_type: "adk_gemini_fullstack"
23
+ commands:
24
+ override:
25
+ install: "npm --prefix frontend install"
26
+ extra:
27
+ dev:
28
+ command: 'make dev-backend & make dev-frontend'
29
+ description: "Start the ADK API server and React frontend development server simultaneously"
30
+ dev-backend:
31
+ command:
32
+ agent_engine: 'uv run adk api_server app --allow_origins="*"'
33
+ cloud_run: 'ALLOW_ORIGINS="*" uv run uvicorn app.server:app --host 0.0.0.0 --port 8000 --reload'
34
+ description: "Start the ADK API server"
35
+ dev-frontend:
36
+ command: 'npm --prefix frontend run dev'
37
+ description: "Start the React frontend development server"
@@ -0,0 +1,58 @@
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="union-attr"
16
+ from google.adk.agents.run_config import RunConfig, StreamingMode
17
+ from google.adk.runners import Runner
18
+ from google.adk.sessions import InMemorySessionService
19
+ from google.genai import types
20
+
21
+ from app.agent import root_agent
22
+
23
+
24
+ def test_agent_stream() -> None:
25
+ """
26
+ Integration test for the agent stream functionality.
27
+ Tests that the agent returns valid streaming responses.
28
+ """
29
+
30
+ session_service = InMemorySessionService()
31
+
32
+ session = session_service.create_session_sync(user_id="test_user", app_name="test")
33
+ runner = Runner(agent=root_agent, session_service=session_service, app_name="test")
34
+
35
+ message = types.Content(
36
+ role="user", parts=[types.Part.from_text(text="Why is the sky blue?")]
37
+ )
38
+
39
+ events = list(
40
+ runner.run(
41
+ new_message=message,
42
+ user_id="test_user",
43
+ session_id=session.id,
44
+ run_config=RunConfig(streaming_mode=StreamingMode.SSE),
45
+ )
46
+ )
47
+ assert len(events) > 0, "Expected at least one message"
48
+
49
+ has_text_content = False
50
+ for event in events:
51
+ if (
52
+ event.content
53
+ and event.content.parts
54
+ and any(part.text for part in event.content.parts)
55
+ ):
56
+ has_text_content = True
57
+ break
58
+ assert has_text_content, "Expected at least one message with text content"
@@ -261,7 +261,7 @@
261
261
  "source": [
262
262
  "### Local Testing\n",
263
263
  "\n",
264
- "> You can run the application locally via the `make backend` command."
264
+ "> You can run the application locally via the `make local-backend` command."
265
265
  ]
266
266
  },
267
267
  {
@@ -18,7 +18,7 @@ settings:
18
18
  requires_data_ingestion: true
19
19
  deployment_targets: ["agent_engine", "cloud_run"]
20
20
  extra_dependencies: [
21
- "google-adk~=1.2.0",
21
+ "google-adk~=1.3.0",
22
22
  "langchain-google-vertexai~=2.0.7",
23
23
  "langchain~=0.3.24",
24
24
  "langchain-core~=0.3.55",
@@ -21,7 +21,7 @@ settings:
21
21
  "langchain~=0.3.14",
22
22
  "langchain-community~=0.3.17",
23
23
  "langchain-openai~=0.3.5",
24
- "langgraph~=0.2.63",
24
+ "langgraph~=0.4.8",
25
25
  "crewai~=0.119.0"
26
26
  ]
27
27
  example_question: "How can I implement a function to sort a list in Python?"
@@ -19,7 +19,7 @@ settings:
19
19
  extra_dependencies: [
20
20
  "langchain-google-vertexai~=2.0.7",
21
21
  "langchain~=0.3.14",
22
- "langgraph~=0.2.63",
22
+ "langgraph~=0.4.8",
23
23
  "langchain-google-vertexai~=2.0.22",
24
24
  "langchain~=0.3.14",
25
25
  "langchain-community~=0.3.17",
@@ -1,11 +1,26 @@
1
1
  install:
2
2
  @command -v uv >/dev/null 2>&1 || { echo "uv is not installed. Installing uv..."; curl -LsSf https://astral.sh/uv/0.6.12/install.sh | sh; source ~/.bashrc; }
3
3
  uv sync --dev{% if cookiecutter.agent_name != 'live_api' and "adk" not in cookiecutter.tags %} --extra streamlit{%- endif %} --extra jupyter --frozen{% if cookiecutter.agent_name == 'live_api' %} && npm --prefix frontend install{%- endif %}
4
+ {%- if cookiecutter.settings.get("commands", {}).get("override", {}).get("install") %} && {{cookiecutter.settings.get("commands", {}).get("override", {}).get("install")}}{%- endif %}
5
+ {%- if cookiecutter.settings.get("commands", {}).get("extra", {}) %}
6
+ {%- for cmd_name, cmd_value in cookiecutter.settings.get("commands", {}).get("extra", {}).items() %}
4
7
 
5
- test:
6
- uv run pytest tests/unit && uv run pytest tests/integration
8
+ {{ cmd_name }}:
9
+ {%- if cmd_value is mapping %}
10
+ {%- if cmd_value.command is mapping and cookiecutter.deployment_target in cmd_value.command %}
11
+ {{ cmd_value.command[cookiecutter.deployment_target] }}
12
+ {%- else %}
13
+ {{ cmd_value.command if cmd_value.command is string else "" }}
14
+ {%- endif %}
15
+ {%- else %}
16
+ {{ cmd_value }}
17
+ {%- endif %}
18
+ {%- endfor %}{%- endif %}
7
19
 
8
20
  playground:
21
+ {%- if cookiecutter.settings.get("commands", {}).get("override", {}).get("playground") %}
22
+ {{cookiecutter.settings.get("commands", {}).get("override", {}).get("playground")}}
23
+ {%- else %}
9
24
  @echo "==============================================================================="
10
25
  @echo "| 🚀 Starting your agent playground... |"
11
26
  @echo "| |"
@@ -27,6 +42,7 @@ playground:
27
42
  {% if cookiecutter.deployment_target == 'agent_engine' %}PYTHONPATH=. {% endif %}uv run streamlit run frontend/streamlit_app.py --browser.serverAddress=localhost --server.enableCORS=false --server.enableXsrfProtection=false
28
43
  {%- endif %}
29
44
  {%- endif %}
45
+ {%- endif %}
30
46
 
31
47
  backend:
32
48
  {%- if cookiecutter.deployment_target == 'cloud_run' %}
@@ -82,6 +98,9 @@ data-ingestion:
82
98
  --pipeline-name="data-ingestion-pipeline")
83
99
  {%- endif %}
84
100
 
101
+ test:
102
+ uv run pytest tests/unit && uv run pytest tests/integration
103
+
85
104
  lint:
86
105
  uv run codespell
87
106
  uv run ruff check . --diff
@@ -46,6 +46,11 @@ make install && make playground
46
46
  | Command | Description |
47
47
  | -------------------- | ------------------------------------------------------------------------------------------- |
48
48
  | `make install` | Install all required dependencies using uv |
49
+ {%- if cookiecutter.settings.get("commands", {}).get("extra", {}) %}
50
+ {%- for cmd_name, cmd_value in cookiecutter.settings.get("commands", {}).get("extra", {}).items() %}
51
+ | `make {{ cmd_name }}` | {% if cmd_value is mapping %}{% if cmd_value.description %}{{ cmd_value.description }}{% else %}{% if cookiecutter.deployment_target in cmd_value %}{{ cmd_value[cookiecutter.deployment_target] }}{% else %}{{ cmd_value.command if cmd_value.command is string else "" }}{% endif %}{% endif %}{% else %}{{ cmd_value }}{% endif %} |
52
+ {%- endfor %}
53
+ {%- endif %}
49
54
  {%- if cookiecutter.deployment_target == 'cloud_run' %}
50
55
  | `make playground` | Launch local development environment with backend and frontend{%- if "adk" in cookiecutter.tags %} - leveraging `adk web` command. {%- endif %}|
51
56
  | `make backend` | Deploy agent to Cloud Run |
@@ -84,7 +89,7 @@ Here’s the recommended workflow for local development:
84
89
  2. **Start the Backend Server:**
85
90
  Open a terminal and run:
86
91
  ```bash
87
- make backend
92
+ make local-backend
88
93
  ```
89
94
  The backend is ready when you see `INFO: Application startup complete.` Wait for this message before starting the frontend.
90
95
 
@@ -96,7 +101,7 @@ Here’s the recommended workflow for local development:
96
101
  ```bash
97
102
  export VERTEXAI=false
98
103
  export GOOGLE_API_KEY="your-google-api-key" # Replace with your actual key
99
- make backend
104
+ make local-backend
100
105
  ```
101
106
  Ensure `GOOGLE_API_KEY` is set correctly in your environment.
102
107
  </details>
@@ -130,7 +135,7 @@ To run the agent using Google Cloud Shell:
130
135
  2. **Start the Backend:**
131
136
  Open a *new* Cloud Shell tab. Set your project: `gcloud config set project [PROJECT_ID]`. Then run:
132
137
  ```bash
133
- make backend
138
+ make local-backend
134
139
  ```
135
140
 
136
141
  3. **Configure Backend Web Preview:**
@@ -99,11 +99,8 @@ exclude = [".venv"]
99
99
 
100
100
  [tool.codespell]
101
101
  ignore-words-list = "rouge"
102
- {% if cookiecutter.agent_name == 'live_api' %}
103
102
  skip = "./locust_env/*,uv.lock,.venv,./frontend,**/*.ipynb"
104
- {% else %}
105
- skip = "./locust_env/*,uv.lock,.venv,**/*.ipynb"
106
- {%- endif %}
103
+
107
104
 
108
105
  [build-system]
109
106
  requires = ["hatchling"]
@@ -191,6 +191,13 @@ def create(
191
191
  if debug:
192
192
  logging.debug(f"Selected agent: {agent}")
193
193
 
194
+ template_path = (
195
+ pathlib.Path(__file__).parent.parent.parent.parent
196
+ / "agents"
197
+ / final_agent
198
+ / "template"
199
+ )
200
+ config = load_template_config(template_path)
194
201
  # Data ingestion and datastore selection
195
202
  if include_data_ingestion or datastore:
196
203
  # If datastore is specified but include_data_ingestion is not, set it to True
@@ -206,13 +213,6 @@ def create(
206
213
  logging.debug(f"Selected datastore type: {datastore}")
207
214
  else:
208
215
  # Check if the agent requires data ingestion
209
- template_path = (
210
- pathlib.Path(__file__).parent.parent.parent.parent
211
- / "agents"
212
- / final_agent
213
- / "template"
214
- )
215
- config = load_template_config(template_path)
216
216
  if config and config.get("settings", {}).get("requires_data_ingestion"):
217
217
  include_data_ingestion = True
218
218
  datastore = prompt_datastore_selection(final_agent)
@@ -322,9 +322,16 @@ def create(
322
322
  )
323
323
  # Determine the correct path to display based on whether output_dir was specified
324
324
  console.print("\n🚀 To get started, run the following command:")
325
- console.print(
326
- f" [bold bright_green]cd {cd_path} && make install && make playground[/]"
327
- )
325
+
326
+ # Check if the agent has a 'dev' command in its settings
327
+ if config["settings"].get("commands", {}).get("extra", {}).get("dev"):
328
+ console.print(
329
+ f" [bold bright_green]cd {cd_path} && make install && make dev[/]"
330
+ )
331
+ else:
332
+ console.print(
333
+ f" [bold bright_green]cd {cd_path} && make install && make playground[/]"
334
+ )
328
335
  except Exception:
329
336
  if debug:
330
337
  logging.exception(
src/cli/utils/template.py CHANGED
@@ -80,7 +80,12 @@ def get_available_agents(deployment_target: str | None = None) -> dict:
80
80
  deployment_target: Optional deployment target to filter agents
81
81
  """
82
82
  # Define priority agents that should appear first
83
- PRIORITY_AGENTS = ["adk_base", "agentic_rag", "langgraph_base_react"]
83
+ PRIORITY_AGENTS = [
84
+ "adk_base",
85
+ "adk_gemini_fullstack",
86
+ "agentic_rag",
87
+ "langgraph_base_react",
88
+ ]
84
89
 
85
90
  agents_list = []
86
91
  priority_agents_dict = dict.fromkeys(PRIORITY_AGENTS) # Track priority agents
@@ -499,15 +504,12 @@ def process_template(
499
504
  copy_data_ingestion_files(project_template, datastore)
500
505
 
501
506
  # Create cookiecutter.json in the template root
502
- # Process extra dependencies
503
- extra_deps = template_config.get("settings", {}).get(
504
- "extra_dependencies", []
505
- )
506
- # Get frontend type from template config
507
- frontend_type = template_config.get("settings", {}).get(
508
- "frontend_type", DEFAULT_FRONTEND
509
- )
510
- tags = template_config.get("settings", {}).get("tags", ["None"])
507
+ # Get settings from template config
508
+ settings = template_config.get("settings", {})
509
+ extra_deps = settings.get("extra_dependencies", [])
510
+ frontend_type = settings.get("frontend_type", DEFAULT_FRONTEND)
511
+ tags = settings.get("tags", ["None"])
512
+
511
513
  cookiecutter_config = {
512
514
  "project_name": "my-project",
513
515
  "agent_name": agent_name,
@@ -516,6 +518,7 @@ def process_template(
516
518
  "example_question": template_config.get("example_question", "").ljust(
517
519
  61
518
520
  ),
521
+ "settings": settings,
519
522
  "tags": tags,
520
523
  "deployment_target": deployment_target or "",
521
524
  "frontend_type": frontend_type,
@@ -15,7 +15,7 @@
15
15
 
16
16
  """
17
17
  This component is derived from the notebook:
18
- https://github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/use-cases/retrieval-augmented_generation/scalable_rag_with_bigframes.ipynb
18
+ https://github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/use-cases/retrieval-augmented-generation/scalable_rag_with_bigframes.ipynb
19
19
 
20
20
  It leverages BigQuery for data processing. We also suggest looking at remote functions for enhanced scalability.
21
21
  """
@@ -24,6 +24,7 @@ from typing import Any
24
24
 
25
25
  import google.auth
26
26
  import vertexai
27
+ from google.adk.artifacts import GcsArtifactService
27
28
  from google.cloud import logging as google_cloud_logging
28
29
  from opentelemetry import trace
29
30
  from opentelemetry.sdk.trace import TracerProvider, export
@@ -210,18 +211,29 @@ def deploy_agent_engine_app(
210
211
  ) -> agent_engines.AgentEngine:
211
212
  """Deploy the agent engine app to Vertex AI."""
212
213
 
213
- staging_bucket = f"gs://{project}-agent-engine"
214
-
214
+ staging_bucket_uri = f"gs://{project}-agent-engine"
215
+ {%- if "adk" in cookiecutter.tags %}
216
+ artifacts_bucket_name = f"{project}-{{cookiecutter.project_name}}-logs-data"
215
217
  create_bucket_if_not_exists(
216
- bucket_name=staging_bucket, project=project, location=location
218
+ bucket_name=artifacts_bucket_name, project=project, location=location
217
219
  )
218
- vertexai.init(project=project, location=location, staging_bucket=staging_bucket)
220
+ {%- endif %}
221
+ create_bucket_if_not_exists(
222
+ bucket_name=staging_bucket_uri, project=project, location=location
223
+ )
224
+
225
+ vertexai.init(project=project, location=location, staging_bucket=staging_bucket_uri)
219
226
 
220
227
  # Read requirements
221
228
  with open(requirements_file) as f:
222
229
  requirements = f.read().strip().split("\n")
223
230
  {% if "adk" in cookiecutter.tags %}
224
- agent_engine = AgentEngineApp(agent=root_agent)
231
+ agent_engine = AgentEngineApp(
232
+ agent=root_agent,
233
+ artifact_service_builder=lambda: GcsArtifactService(
234
+ bucket_name=artifacts_bucket_name
235
+ ),
236
+ )
225
237
  {% else %}
226
238
  agent_engine = AgentEngineApp(project_id=project)
227
239
  {% endif %}
@@ -14,17 +14,28 @@
14
14
  {% if "adk" in cookiecutter.tags %}
15
15
  import os
16
16
 
17
+ import google.auth
17
18
  from fastapi import FastAPI
18
19
  from google.adk.cli.fast_api import get_fast_api_app
19
20
  from google.cloud import logging as google_cloud_logging
20
21
  from opentelemetry import trace
21
22
  from opentelemetry.sdk.trace import TracerProvider, export
22
23
 
24
+ from app.utils.gcs import create_bucket_if_not_exists
23
25
  from app.utils.tracing import CloudTraceLoggingSpanExporter
24
26
  from app.utils.typing import Feedback
25
27
 
28
+ _, project_id = google.auth.default()
26
29
  logging_client = google_cloud_logging.Client()
27
30
  logger = logging_client.logger(__name__)
31
+ allow_origins = (
32
+ os.getenv("ALLOW_ORIGINS", "").split(",") if os.getenv("ALLOW_ORIGINS") else None
33
+ )
34
+
35
+ bucket_name = f"gs://{project_id}-{{cookiecutter.project_name}}-logs-data"
36
+ create_bucket_if_not_exists(
37
+ bucket_name=bucket_name, project=project_id, location="us-central1"
38
+ )
28
39
 
29
40
  provider = TracerProvider()
30
41
  processor = export.BatchSpanProcessor(CloudTraceLoggingSpanExporter())
@@ -32,8 +43,12 @@ provider.add_span_processor(processor)
32
43
  trace.set_tracer_provider(provider)
33
44
 
34
45
  AGENT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
35
- app: FastAPI = get_fast_api_app(agents_dir=AGENT_DIR, web=True)
36
-
46
+ app: FastAPI = get_fast_api_app(
47
+ agents_dir=AGENT_DIR,
48
+ web=True,
49
+ artifact_service_uri=bucket_name,
50
+ allow_origins=allow_origins,
51
+ )
37
52
  app.title = "{{cookiecutter.project_name}}"
38
53
  app.description = "API for interacting with the Agent {{cookiecutter.project_name}}"
39
54
  {%- else %}
@@ -157,7 +157,7 @@ def test_chat_stream(server_fixture: subprocess.Popen[str]) -> None:
157
157
  }
158
158
  {% endif %}
159
159
  response = requests.post(
160
- STREAM_URL, headers=HEADERS, json=data, stream=True, timeout=10
160
+ STREAM_URL, headers=HEADERS, json=data, stream=True, timeout=60
161
161
  )
162
162
  assert response.status_code == 200
163
163