Skip to content

Commit 09920c5

Browse files
authored
Feat/adk go template (#670)
* feat: add Go ADK template support - Add adk_base_go agent template with Go implementation - Add Go base templates with CI/CD pipelines (GitHub Actions, Cloud Build) - Add Cloud Run deployment target for Go - Refactor template structure to support shared and language-specific files - Update CLI to handle Go project creation and enhancement - Add Go-specific e2e and load testing support * docs: add Go template support to documentation - Update development guide with Go project structure and workflow - Update getting-started with Go prerequisites and examples - Add Go agent example to create CLI reference - Auto-select deployment target when only one option available
1 parent becc70f commit 09920c5

File tree

121 files changed

+3795
-1039
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

121 files changed

+3795
-1039
lines changed

.cloudbuild/ci/test_pipeline_parity.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ steps:
2222
- |
2323
uv sync --dev --locked
2424
25-
# Run pipeline parity tests
25+
# Run pipeline parity tests (Python and Go templates in parallel)
2626
- name: "europe-west4-docker.pkg.dev/production-ai-template/starter-pack/e2e-tests"
2727
id: pipeline-parity-tests
2828
entrypoint: /bin/bash
2929
args:
3030
- "-c"
3131
- |
32-
uv run pytest tests/integration/test_pipeline_parity.py -v
32+
uv run pytest tests/integration/test_pipeline_parity.py -v -n auto
3333
3434
3535
logsBucket: gs://${PROJECT_ID}-logs-data/build-logs

.cloudbuild/terraform/build_triggers.tf

Lines changed: 110 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,11 @@ locals {
8181
value = "langgraph_base,cloud_run,-dir,tag"
8282
},
8383
{
84-
name = "agentic_rag-agent_engine-vertex_ai_search"
84+
name = "agentic_rag-agent_engine-vertex_ai_search"
8585
value = "agentic_rag,agent_engine,--include-data-ingestion,--datastore,vertex_ai_search"
8686
},
8787
{
88-
name = "agentic_rag-cloud_run-vertex_ai_vector_search"
88+
name = "agentic_rag-cloud_run-vertex_ai_vector_search"
8989
value = "agentic_rag,cloud_run,--include-data-ingestion,--datastore,vertex_ai_vector_search"
9090
},
9191
{
@@ -112,15 +112,38 @@ locals {
112112
name = "adk_a2a_base-cloud_run"
113113
value = "adk_a2a_base,cloud_run"
114114
},
115+
{
116+
name = "adk_base_go-cloud_run"
117+
value = "adk_base_go,cloud_run"
118+
},
115119
]
116120

117-
agent_testing_included_files = { for combo in local.agent_testing_combinations :
118-
combo.name => [
121+
# Go-specific included files (different paths from Python)
122+
# Only triggers when Go-specific template files change
123+
go_agent_testing_included_files = {
124+
"adk_base_go-cloud_run" = [
125+
# Go agent-specific files
126+
"agent_starter_pack/agents/adk_base_go/**",
127+
# Shared base template (affects all languages)
128+
"agent_starter_pack/base_templates/_shared/**",
129+
# Go base template
130+
"agent_starter_pack/base_templates/go/**",
131+
# Go deployment target
132+
"agent_starter_pack/deployment_targets/cloud_run/go/**",
133+
]
134+
}
135+
136+
agent_testing_included_files = {
137+
# Python agents use base_template paths
138+
for combo in local.agent_testing_combinations :
139+
combo.name => endswith(split(",", combo.value)[0], "_go") ? local.go_agent_testing_included_files[combo.name] : [
119140
# Only include files for the specific agent being tested
120141
"agent_starter_pack/agents/${split(",", combo.value)[0]}/**",
121142
# Common files that affect all agents
122143
"agent_starter_pack/cli/**",
123144
"agent_starter_pack/base_template/**",
145+
"agent_starter_pack/base_templates/_shared/**",
146+
"agent_starter_pack/base_templates/python/**",
124147
"agent_starter_pack/deployment_targets/**",
125148
"tests/integration/test_template_linting.py",
126149
"tests/integration/test_templated_patterns.py",
@@ -139,7 +162,7 @@ agent_testing_included_files = { for combo in local.agent_testing_combinations :
139162
value = "adk_base,cloud_run,--cicd-runner,github_actions"
140163
},
141164
{
142-
name = "agentic_rag-agent_engine-vertex_ai_search-github"
165+
name = "agentic_rag-agent_engine-vertex_ai_search-github"
143166
value = "agentic_rag,agent_engine,--include-data-ingestion,--datastore,vertex_ai_search,--cicd-runner,github_actions"
144167
},
145168
{
@@ -155,15 +178,15 @@ agent_testing_included_files = { for combo in local.agent_testing_combinations :
155178
value = "adk_base,cloud_run,-dir,tag"
156179
},
157180
{
158-
name = "langgraph_base-agent_engine"
181+
name = "langgraph_base-agent_engine"
159182
value = "langgraph_base,agent_engine"
160183
},
161184
{
162-
name = "agentic_rag-agent_engine-vertex_ai_search"
185+
name = "agentic_rag-agent_engine-vertex_ai_search"
163186
value = "agentic_rag,agent_engine,--include-data-ingestion,--datastore,vertex_ai_search"
164187
},
165188
{
166-
name = "agentic_rag-cloud_run-vertex_ai_vector_search"
189+
name = "agentic_rag-cloud_run-vertex_ai_vector_search"
167190
value = "agentic_rag,cloud_run,--include-data-ingestion,--datastore,vertex_ai_vector_search"
168191
},
169192
{
@@ -186,43 +209,67 @@ agent_testing_included_files = { for combo in local.agent_testing_combinations :
186209
name = "adk_a2a_base-cloud_run"
187210
value = "adk_a2a_base,cloud_run"
188211
},
212+
{
213+
name = "adk_base_go-cloud_run"
214+
value = "adk_base_go,cloud_run"
215+
},
189216
]
217+
218+
# Go-specific E2E included files
219+
# Only triggers when Go-specific template files change
220+
go_e2e_agent_deployment_included_files = {
221+
"adk_base_go-cloud_run" = [
222+
# Go agent-specific files
223+
"agent_starter_pack/agents/adk_base_go/**",
224+
# Shared base template
225+
"agent_starter_pack/base_templates/_shared/**",
226+
# Go base template
227+
"agent_starter_pack/base_templates/go/**",
228+
# Go deployment target
229+
"agent_starter_pack/deployment_targets/cloud_run/go/**",
230+
]
231+
}
232+
190233
# Create a safe trigger name by replacing underscores with hyphens and dots with hyphens
191234
# This ensures we have valid trigger names that don't exceed character limits
192235
trigger_name_safe = { for combo in local.agent_testing_combinations :
193-
combo.name => replace(replace(combo.name, "_", "-"), ".", "-")
194-
}
236+
combo.name => replace(replace(combo.name, "_", "-"), ".", "-")
237+
}
195238

196239
# Create safe trigger names for e2e deployment combinations
197240
e2e_trigger_name_safe = { for combo in local.e2e_agent_deployment_combinations :
198-
combo.name => replace(replace(combo.name, "_", "-"), ".", "-")
199-
}
241+
combo.name => replace(replace(combo.name, "_", "-"), ".", "-")
242+
}
200243

201244
e2e_agent_deployment_included_files = { for combo in local.e2e_agent_deployment_combinations :
202-
combo.name => combo.name == "adk_base-cloud_run-cloud_sql" ? [
203-
"agent_starter_pack/deployment_targets/cloud_run/**",
204-
"pyproject.toml",
205-
] : substr(combo.name, 0, 11) == "agentic_rag" ? [
206-
"agent_starter_pack/agents/agentic_rag/**",
207-
"agent_starter_pack/data_ingestion/**",
208-
"pyproject.toml",
209-
] : substr(combo.name, 0, 8) == "adk_live" ? [
210-
"agent_starter_pack/agents/adk_live/**",
211-
"pyproject.toml",
212-
] : [
213-
# Only include files for the specific agent being tested
214-
"agent_starter_pack/agents/${split(",", combo.value)[0]}/**",
215-
# Common files that affect all agents
216-
"agent_starter_pack/cli/**",
217-
"agent_starter_pack/base_template/**",
218-
"agent_starter_pack/data_ingestion/**",
219-
"agent_starter_pack/deployment_targets/**",
220-
"tests/cicd/test_e2e_deployment.py",
221-
"agent_starter_pack/resources/locks/**",
222-
"pyproject.toml",
223-
"uv.lock",
224-
".cloudbuild"
225-
]
245+
combo.name => endswith(split(",", combo.value)[0], "_go") ? local.go_e2e_agent_deployment_included_files[combo.name] : (
246+
combo.name == "adk_base-cloud_run-cloud_sql" ? [
247+
"agent_starter_pack/deployment_targets/cloud_run/**",
248+
"pyproject.toml",
249+
] : substr(combo.name, 0, 11) == "agentic_rag" ? [
250+
"agent_starter_pack/agents/agentic_rag/**",
251+
"agent_starter_pack/data_ingestion/**",
252+
"pyproject.toml",
253+
] : substr(combo.name, 0, 8) == "adk_live" ? [
254+
"agent_starter_pack/agents/adk_live/**",
255+
"pyproject.toml",
256+
] : [
257+
# Only include files for the specific agent being tested
258+
"agent_starter_pack/agents/${split(",", combo.value)[0]}/**",
259+
# Common files that affect all agents
260+
"agent_starter_pack/cli/**",
261+
"agent_starter_pack/base_template/**",
262+
"agent_starter_pack/base_templates/_shared/**",
263+
"agent_starter_pack/base_templates/python/**",
264+
"agent_starter_pack/data_ingestion/**",
265+
"agent_starter_pack/deployment_targets/**",
266+
"tests/cicd/test_e2e_deployment.py",
267+
"agent_starter_pack/resources/locks/**",
268+
"pyproject.toml",
269+
"uv.lock",
270+
".cloudbuild"
271+
]
272+
)
226273
}
227274
}
228275

@@ -241,9 +288,9 @@ resource "google_cloudbuild_trigger" "pr_build_use_wheel" {
241288
}
242289
}
243290

244-
filename = ".cloudbuild/ci/build_use_wheel.yaml"
245-
included_files = local.common_included_files
246-
ignored_files = local.common_ignored_files
291+
filename = ".cloudbuild/ci/build_use_wheel.yaml"
292+
included_files = local.common_included_files
293+
ignored_files = local.common_ignored_files
247294
include_build_logs = "INCLUDE_BUILD_LOGS_WITH_STATUS"
248295
}
249296

@@ -263,9 +310,9 @@ resource "google_cloudbuild_trigger" "pr_tests" {
263310
}
264311
}
265312

266-
filename = ".cloudbuild/ci/test.yaml"
267-
included_files = local.common_included_files
268-
ignored_files = local.common_ignored_files
313+
filename = ".cloudbuild/ci/test.yaml"
314+
included_files = local.common_included_files
315+
ignored_files = local.common_ignored_files
269316
include_build_logs = "INCLUDE_BUILD_LOGS_WITH_STATUS"
270317
}
271318

@@ -285,16 +332,16 @@ resource "google_cloudbuild_trigger" "pr_lint" {
285332
}
286333
}
287334

288-
filename = ".cloudbuild/ci/lint.yaml"
289-
included_files = local.common_included_files
290-
ignored_files = local.common_ignored_files
335+
filename = ".cloudbuild/ci/lint.yaml"
336+
included_files = local.common_included_files
337+
ignored_files = local.common_ignored_files
291338
include_build_logs = "INCLUDE_BUILD_LOGS_WITH_STATUS"
292339
}
293340

294341
# c. Create Templated Agents Lint trigger for PRs - one for each agent/deployment combination:
295342
resource "google_cloudbuild_trigger" "pr_templated_agents_lint" {
296343
for_each = { for combo in local.agent_testing_combinations : combo.name => combo }
297-
344+
298345
name = "lint-${local.trigger_name_safe[each.key]}"
299346
project = var.cicd_runner_project_id
300347
location = var.region
@@ -309,9 +356,9 @@ resource "google_cloudbuild_trigger" "pr_templated_agents_lint" {
309356
}
310357
}
311358

312-
filename = ".cloudbuild/ci/lint_templated_agents.yaml"
313-
included_files = local.agent_testing_included_files[each.key]
314-
ignored_files = local.common_ignored_files
359+
filename = ".cloudbuild/ci/lint_templated_agents.yaml"
360+
included_files = local.agent_testing_included_files[each.key]
361+
ignored_files = local.common_ignored_files
315362
include_build_logs = "INCLUDE_BUILD_LOGS_WITH_STATUS"
316363

317364
substitutions = {
@@ -337,9 +384,9 @@ resource "google_cloudbuild_trigger" "pr_templated_agents_test" {
337384
}
338385
}
339386

340-
filename = ".cloudbuild/ci/test_templated_agents.yaml"
341-
included_files = local.agent_testing_included_files[each.key]
342-
ignored_files = local.common_ignored_files
387+
filename = ".cloudbuild/ci/test_templated_agents.yaml"
388+
included_files = local.agent_testing_included_files[each.key]
389+
ignored_files = local.common_ignored_files
343390
include_build_logs = "INCLUDE_BUILD_LOGS_WITH_STATUS"
344391

345392
substitutions = {
@@ -364,9 +411,9 @@ resource "google_cloudbuild_trigger" "main_e2e_deployment_test" {
364411
}
365412
}
366413

367-
filename = ".cloudbuild/cd/test_e2e.yaml"
368-
included_files = local.e2e_agent_deployment_included_files[each.key]
369-
ignored_files = concat(local.common_ignored_files, local.gemini_enterprise_files)
414+
filename = ".cloudbuild/cd/test_e2e.yaml"
415+
included_files = local.e2e_agent_deployment_included_files[each.key]
416+
ignored_files = concat(local.common_ignored_files, local.gemini_enterprise_files)
370417
include_build_logs = "INCLUDE_BUILD_LOGS_UNSPECIFIED"
371418

372419
substitutions = {
@@ -418,7 +465,7 @@ resource "google_cloudbuild_trigger" "pr_test_makefile" {
418465

419466
filename = ".cloudbuild/ci/test_makefile.yaml"
420467
included_files = local.makefile_usability_included_files
421-
ignored_files = ["**/*.md"] # Don't ignore Makefiles for this trigger
468+
ignored_files = ["**/*.md"] # Don't ignore Makefiles for this trigger
422469
include_build_logs = "INCLUDE_BUILD_LOGS_WITH_STATUS"
423470
}
424471

@@ -438,7 +485,7 @@ resource "google_cloudbuild_trigger" "pr_test_pipeline_parity" {
438485
}
439486
}
440487

441-
filename = ".cloudbuild/ci/test_pipeline_parity.yaml"
488+
filename = ".cloudbuild/ci/test_pipeline_parity.yaml"
442489
included_files = [
443490
"tests/integration/test_pipeline_parity.py",
444491
"agent_starter_pack/cli/**",
@@ -468,7 +515,7 @@ resource "google_cloudbuild_trigger" "pr_test_agent_directory" {
468515
}
469516
}
470517

471-
filename = ".cloudbuild/ci/test_agent_directory.yaml"
518+
filename = ".cloudbuild/ci/test_agent_directory.yaml"
472519
included_files = [
473520
"pyproject.toml",
474521
"uv.lock",
@@ -494,12 +541,12 @@ resource "google_cloudbuild_trigger" "main_e2e_gemini_enterprise_test" {
494541
}
495542
}
496543

497-
filename = ".cloudbuild/cd/test_gemini_enterprise.yaml"
544+
filename = ".cloudbuild/cd/test_gemini_enterprise.yaml"
498545
included_files = [
499-
"pyproject.toml", # Triggers on releases
500-
"agent_starter_pack/cli/commands/register_gemini_enterprise.py", # Registration code changes
501-
"tests/cicd/test_gemini_enterprise_registration.py", # Test changes
502-
".cloudbuild/cd/test_gemini_enterprise.yaml", # Pipeline changes
546+
"pyproject.toml", # Triggers on releases
547+
"agent_starter_pack/cli/commands/register_gemini_enterprise.py", # Registration code changes
548+
"tests/cicd/test_gemini_enterprise_registration.py", # Test changes
549+
".cloudbuild/cd/test_gemini_enterprise.yaml", # Pipeline changes
503550
]
504551
ignored_files = local.common_ignored_files
505552
include_build_logs = "INCLUDE_BUILD_LOGS_UNSPECIFIED"

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ celerybeat.pid
109109

110110
# Environments
111111
.env
112+
!agent_starter_pack/base_templates/go/.env
112113
.venv
113114
.venv*
114115
env/

agent_starter_pack/agents/adk_a2a_base/.template/templateconfig.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
description: "A base ReAct agent built with Google's Agent Development Kit (ADK) and Agent2Agent (A2A) Protocol. #experimental"
15+
description: "ReAct agent with A2A protocol [experimental]"
1616
example_question: "What's the weather in San Francisco?"
1717
settings:
1818
requires_data_ingestion: false

agent_starter_pack/agents/adk_base/.template/templateconfig.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
description: "A base ReAct agent built with Google's Agent Development Kit (ADK)"
15+
description: "Simple ReAct agent"
1616
example_question: "What's the weather in San Francisco?"
1717
settings:
1818
requires_data_ingestion: false
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
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: "Simple ReAct agent"
16+
example_question: "What's the weather in San Francisco?"
17+
settings:
18+
language: "go"
19+
requires_data_ingestion: false
20+
requires_session: false
21+
deployment_targets: ["cloud_run"]
22+
extra_dependencies: []
23+
tags: ["adk", "go", "a2a"]
24+
frontend_type: "None"
25+
agent_directory: "agent"

0 commit comments

Comments
 (0)