├── tests
├── __init__.py
├── utils
│ └── __init__.py
├── cicd
│ └── example.env
├── fixtures
│ ├── makefile_hashes.json
│ └── makefile_snapshots
│ │ ├── adk_base_agent_engine_no_data.makefile
│ │ ├── agent_with_custom_commands.makefile
│ │ ├── langgraph_cloud_run_no_data.makefile
│ │ ├── adk_base_cloud_run_no_data.makefile
│ │ └── agent_with_agent_garden.makefile
├── cli
│ ├── commands
│ │ └── test_list.py
│ └── utils
│ │ └── test_cicd.py
├── integration
│ └── utils.py
├── test_frontend
│ └── test_utils
│ │ ├── test_multimodal_utils.py
│ │ └── test_local_chat_history.py
└── unit
│ └── README_MAKEFILE_TESTS.md
├── agent_starter_pack
├── deployment_targets
│ ├── agent_engine
│ │ ├── tests
│ │ │ └── load_test
│ │ │ │ ├── .results
│ │ │ │ └── .placeholder
│ │ │ │ └── README.md
│ │ └── deployment_metadata.json
│ └── cloud_run
│ │ └── Dockerfile
├── frontends
│ ├── adk_live_react
│ │ └── frontend
│ │ │ ├── public
│ │ │ ├── robots.txt
│ │ │ ├── favicon.ico
│ │ │ └── index.html
│ │ │ ├── tsconfig.json
│ │ │ ├── src
│ │ │ ├── react-app-env.d.ts
│ │ │ ├── hooks
│ │ │ │ ├── use-media-stream-mux.ts
│ │ │ │ ├── use-webcam.ts
│ │ │ │ └── use-screen-capture.ts
│ │ │ ├── setupTests.ts
│ │ │ ├── App.test.tsx
│ │ │ ├── index.css
│ │ │ ├── reportWebVitals.ts
│ │ │ ├── index.tsx
│ │ │ ├── utils
│ │ │ │ ├── audioworklet-registry.ts
│ │ │ │ ├── store-logger.ts
│ │ │ │ └── worklets
│ │ │ │ │ ├── vol-meter.ts
│ │ │ │ │ └── audio-processing.ts
│ │ │ ├── contexts
│ │ │ │ └── LiveAPIContext.tsx
│ │ │ ├── components
│ │ │ │ └── audio-pulse
│ │ │ │ │ ├── audio-pulse.scss
│ │ │ │ │ └── AudioPulse.tsx
│ │ │ └── App.tsx
│ │ │ └── package.json
│ └── streamlit
│ │ └── frontend
│ │ ├── style
│ │ └── app_markdown.py
│ │ └── utils
│ │ ├── message_editing.py
│ │ └── chat_utils.py
├── base_template
│ ├── GEMINI.md
│ ├── deployment
│ │ ├── README.md
│ │ └── terraform
│ │ │ ├── dev
│ │ │ ├── vars
│ │ │ │ └── env.tfvars
│ │ │ ├── providers.tf
│ │ │ ├── apis.tf
│ │ │ └── log_sinks.tf
│ │ │ ├── providers.tf
│ │ │ ├── vars
│ │ │ └── env.tfvars
│ │ │ ├── apis.tf
│ │ │ ├── service_accounts.tf
│ │ │ ├── locals.tf
│ │ │ ├── {% if cookiecutter.cicd_runner == 'github_actions' %}wif.tf{% else %}unused_wif.tf{% endif %}
│ │ │ └── log_sinks.tf
│ ├── tests
│ │ └── unit
│ │ │ └── test_dummy.py
│ ├── {{cookiecutter.agent_directory}}
│ │ └── utils
│ │ │ └── gcs.py
│ ├── {% if cookiecutter.cicd_runner == 'google_cloud_build' %}.cloudbuild{% else %}unused_.cloudbuild{% endif %}
│ │ └── pr_checks.yaml
│ └── {% if cookiecutter.cicd_runner == 'github_actions' %}.github{% else %}unused_github{% endif %}
│ │ └── workflows
│ │ └── pr_checks.yaml
├── resources
│ ├── idx
│ │ ├── idx-template.json
│ │ ├── idx-template.nix
│ │ └── .idx
│ │ │ └── dev.nix
│ └── containers
│ │ ├── data_processing
│ │ └── Dockerfile
│ │ └── e2e-tests
│ │ └── Dockerfile
├── agents
│ ├── README.md
│ ├── langgraph_base_react
│ │ ├── README.md
│ │ ├── .template
│ │ │ └── templateconfig.yaml
│ │ ├── app
│ │ │ └── agent.py
│ │ └── tests
│ │ │ └── integration
│ │ │ └── test_agent.py
│ ├── adk_base
│ │ ├── app
│ │ │ ├── __init__.py
│ │ │ └── agent.py
│ │ ├── README.md
│ │ ├── .template
│ │ │ └── templateconfig.yaml
│ │ └── tests
│ │ │ └── integration
│ │ │ └── test_agent.py
│ ├── agentic_rag
│ │ ├── app
│ │ │ ├── __init__.py
│ │ │ └── templates.py
│ │ ├── .template
│ │ │ └── templateconfig.yaml
│ │ ├── README.md
│ │ └── tests
│ │ │ └── integration
│ │ │ └── test_agent.py
│ ├── adk_live
│ │ ├── .template
│ │ │ └── templateconfig.yaml
│ │ ├── tests
│ │ │ └── unit
│ │ │ │ └── test_dummy.py
│ │ ├── app
│ │ │ └── agent.py
│ │ └── README.md
│ └── crewai_coding_crew
│ │ ├── .template
│ │ └── templateconfig.yaml
│ │ ├── app
│ │ ├── crew
│ │ │ ├── config
│ │ │ │ ├── agents.yaml
│ │ │ │ └── tasks.yaml
│ │ │ └── crew.py
│ │ └── agent.py
│ │ ├── README.md
│ │ └── tests
│ │ └── integration
│ │ └── test_agent.py
├── data_ingestion
│ └── pyproject.toml
├── cli
│ ├── utils
│ │ ├── datastores.py
│ │ ├── __init__.py
│ │ └── version.py
│ └── main.py
└── utils
│ └── lock_utils.py
├── docs
├── images
│ ├── icon.png
│ ├── logo.png
│ ├── adk_logo.png
│ ├── why_sp_edited.png
│ ├── prototype_to_prod.png
│ ├── why_starter_pack.png
│ ├── adk_gemini_fullstack.gif
│ ├── ags_high_level_architecture.png
│ ├── agent_starter_pack_screenshot.png
│ └── adk_gemini_fullstack_architecture.png
├── package.json
├── cli
│ ├── index.md
│ └── list.md
├── guide
│ ├── video-tutorials.md
│ ├── community-showcase.md
│ ├── observability.md
│ ├── troubleshooting.md
│ ├── getting-started.md
│ └── data-ingestion.md
├── index.md
└── remote-templates
│ └── index.md
├── .cloudbuild
├── terraform
│ ├── backend.tf
│ ├── vars
│ │ └── env.tfvars
│ ├── storage.tf
│ ├── apis.tf
│ ├── variables.tf
│ └── service_account.tf
├── ci
│ ├── build_use_wheel.yaml
│ ├── test.yaml
│ ├── test_makefile.yaml
│ ├── test_remote_template.yaml
│ ├── test_pipeline_parity.yaml
│ ├── lint_templated_agents.yaml
│ ├── test_templated_agents.yaml
│ └── lint.yaml
└── cd
│ └── test_e2e.yaml
├── Makefile
├── .github
└── workflows
│ └── docs.yml
└── CODE_OF_CONDUCT.md
/tests/__init__.py:
--------------------------------------------------------------------------------
1 | # Empty file to make the directory a package
2 |
--------------------------------------------------------------------------------
/tests/utils/__init__.py:
--------------------------------------------------------------------------------
1 | # Empty file to make the directory a package
2 |
--------------------------------------------------------------------------------
/agent_starter_pack/deployment_targets/agent_engine/tests/load_test/.results/.placeholder:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/images/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Otutu11/agent-starter-pack/main/docs/images/icon.png
--------------------------------------------------------------------------------
/docs/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Otutu11/agent-starter-pack/main/docs/images/logo.png
--------------------------------------------------------------------------------
/docs/images/adk_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Otutu11/agent-starter-pack/main/docs/images/adk_logo.png
--------------------------------------------------------------------------------
/docs/images/why_sp_edited.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Otutu11/agent-starter-pack/main/docs/images/why_sp_edited.png
--------------------------------------------------------------------------------
/docs/images/prototype_to_prod.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Otutu11/agent-starter-pack/main/docs/images/prototype_to_prod.png
--------------------------------------------------------------------------------
/docs/images/why_starter_pack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Otutu11/agent-starter-pack/main/docs/images/why_starter_pack.png
--------------------------------------------------------------------------------
/docs/images/adk_gemini_fullstack.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Otutu11/agent-starter-pack/main/docs/images/adk_gemini_fullstack.gif
--------------------------------------------------------------------------------
/docs/images/ags_high_level_architecture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Otutu11/agent-starter-pack/main/docs/images/ags_high_level_architecture.png
--------------------------------------------------------------------------------
/agent_starter_pack/frontends/adk_live_react/frontend/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/docs/images/agent_starter_pack_screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Otutu11/agent-starter-pack/main/docs/images/agent_starter_pack_screenshot.png
--------------------------------------------------------------------------------
/agent_starter_pack/deployment_targets/agent_engine/deployment_metadata.json:
--------------------------------------------------------------------------------
1 | {
2 | "remote_agent_engine_id": "None",
3 | "deployment_timestamp": "None"
4 | }
--------------------------------------------------------------------------------
/docs/images/adk_gemini_fullstack_architecture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Otutu11/agent-starter-pack/main/docs/images/adk_gemini_fullstack_architecture.png
--------------------------------------------------------------------------------
/.cloudbuild/terraform/backend.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | backend "gcs" {
3 | bucket = "agent-starter-pack-cicd-terraform-state"
4 | prefix = "cloudbuild"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/agent_starter_pack/base_template/GEMINI.md:
--------------------------------------------------------------------------------
1 | Coding Agent guidance:
2 | {%- if cookiecutter.is_adk %}
3 | {{ cookiecutter.adk_cheatsheet }}
4 | {%- endif %}
5 | {{ cookiecutter.llm_txt }}
--------------------------------------------------------------------------------
/agent_starter_pack/frontends/adk_live_react/frontend/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Otutu11/agent-starter-pack/main/agent_starter_pack/frontends/adk_live_react/frontend/public/favicon.ico
--------------------------------------------------------------------------------
/docs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "project-docs",
3 | "version": "1.0.0",
4 | "description": "Project documentation",
5 | "main": "index.js",
6 | "type": "module",
7 | "scripts": {
8 | "docs:dev": "vitepress dev",
9 | "docs:build": "vitepress build",
10 | "docs:preview": "vitepress preview"
11 | },
12 | "devDependencies": {
13 | "vitepress": "^1.6.3"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/.cloudbuild/terraform/vars/env.tfvars:
--------------------------------------------------------------------------------
1 | cicd_runner_project_id = "agent-starter-pack-cicd"
2 |
3 | region = "europe-west4"
4 |
5 | host_connection_name = "git-connection"
6 |
7 | repository_name = "GoogleCloudPlatform-agent-starter-pack"
8 |
9 | e2e_test_project_mapping = {
10 | dev = "agent-starter-pack-e2e-dev"
11 | staging = "agent-starter-pack-e2e-st"
12 | prod = "agent-starter-pack-e2e-pr"
13 | }
14 |
--------------------------------------------------------------------------------
/agent_starter_pack/resources/idx/idx-template.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Agent Starter Pack",
3 | "description": "Production-ready Gen AI Agent templates for Google Cloud. Addressing common challenges (Deployment & Operations, Evaluation, Customization, Observability) in building and deploying GenAI agents.",
4 | "icon": "https://github.com/GoogleCloudPlatform/agent-starter-pack/blob/main/docs/images/icon.png?raw=true",
5 | "params": []
6 | }
7 |
--------------------------------------------------------------------------------
/agent_starter_pack/agents/README.md:
--------------------------------------------------------------------------------
1 | # Agent Templates
2 |
3 | This directory contains template implementations for various agents designed to work with the Agent Starter Pack templating system.
4 | Feel free to browse through these folders to preview what each template offers.
5 | Direct cloning of this repository isn't necessary to utilize these templates.
6 |
7 | For setup instructions and getting started, please refer to the main [README](/README.md) which explains how to install and use the Agent Starter Pack.
8 |
--------------------------------------------------------------------------------
/agent_starter_pack/data_ingestion/pyproject.toml:
--------------------------------------------------------------------------------
1 | [project]
2 | name = "data-ingestion-pipeline"
3 | version = "0.1.0"
4 | description = "Data ingestion pipeline for RAG retriever"
5 | readme = "README.md"
6 | requires-python = ">=3.9, <=3.13"
7 | dependencies = [
8 | "google-cloud-aiplatform>=1.80.0",
9 | "google-cloud-pipeline-components>=2.19.0",
10 | "kfp>=1.4.0",
11 | ]
12 |
13 | [build-system]
14 | requires = ["hatchling"]
15 | build-backend = "hatchling.build"
16 |
17 | [tool.hatch.build.targets.wheel]
18 | packages = ["data_ingestion_pipeline"]
--------------------------------------------------------------------------------
/agent_starter_pack/agents/langgraph_base_react/README.md:
--------------------------------------------------------------------------------
1 | # LangGraph Base React Agent
2 |
3 | A minimal example demonstrating how to build a ReAct agent using LangGraph. This agent serves as an excellent starting point for developers looking to implement LangGraph-based solutions.
4 |
5 | ## Key Features
6 |
7 | - **Simple Architecture**: Shows the basic building blocks of a LangGraph agent
8 | - **Streaming Support**: Includes streaming response capability using Vertex AI
9 | - **Sample Tool Integration**: Includes a basic search tool to demonstrate tool usage
10 |
--------------------------------------------------------------------------------
/tests/cicd/example.env:
--------------------------------------------------------------------------------
1 | # Example environment variables for E2E testing
2 | # Replace these values with your actual project IDs and credentials
3 |
4 | # GCP Project IDs for different environments
5 | E2E_DEV_PROJECT="your-dev-project-id"
6 | E2E_STAGING_PROJECT="your-staging-project-id"
7 | E2E_PROD_PROJECT="your-prod-project-id"
8 | E2E_CICD_PROJECT="your-cicd-project-id"
9 |
10 | # GitHub credentials
11 | GITHUB_PAT="your-github-personal-access-token"
12 | GITHUB_APP_INSTALLATION_ID="your-github-app-installation-id"
13 |
14 | # Enable E2E tests (set to 1 to run)
15 | RUN_E2E_TESTS=1
--------------------------------------------------------------------------------
/docs/cli/index.md:
--------------------------------------------------------------------------------
1 | # CLI Reference
2 |
3 | The Agent Starter Pack provides a command-line interface (CLI) to create and setup Generative AI Agent templates in Google Cloud.
4 |
5 | ## Available Commands
6 |
7 | - [`create`](create.md) - Create a new generative AI application project
8 | - [`setup-cicd`](setup_cicd.md) - Set up CI/CD pipeline for your project
9 | - [`enhance`](enhance.md) - Add agent-starter-pack capabilities to existing projects without creating a new directory
10 | - [`list`](list.md) - List available agents and templates
11 |
12 | For detailed usage instructions, click on the command links above.
13 |
--------------------------------------------------------------------------------
/agent_starter_pack/agents/adk_base/app/__init__.py:
--------------------------------------------------------------------------------
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 | from .agent import root_agent
16 |
17 | __all__ = ["root_agent"]
18 |
--------------------------------------------------------------------------------
/agent_starter_pack/agents/agentic_rag/app/__init__.py:
--------------------------------------------------------------------------------
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 | from .agent import root_agent
16 |
17 | __all__ = ["root_agent"]
18 |
--------------------------------------------------------------------------------
/agent_starter_pack/frontends/adk_live_react/frontend/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2022",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "esModuleInterop": true,
8 | "allowSyntheticDefaultImports": true,
9 | "strict": true,
10 | "forceConsistentCasingInFileNames": true,
11 | "noFallthroughCasesInSwitch": true,
12 | "module": "esnext",
13 | "moduleResolution": "node",
14 | "resolveJsonModule": true,
15 | "isolatedModules": true,
16 | "noEmit": true,
17 | "jsx": "preserve"
18 | },
19 | "include": ["src", "src/**/*"],
20 | "ts-node": {
21 | "compilerOptions": {
22 | "module": "commonjs"
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/agent_starter_pack/base_template/deployment/README.md:
--------------------------------------------------------------------------------
1 | # Deployment
2 |
3 | This directory contains the Terraform configurations for provisioning the necessary Google Cloud infrastructure for your agent.
4 |
5 | The recommended way to deploy the infrastructure and set up the CI/CD pipeline is by using the `agent-starter-pack setup-cicd` command from the root of your project.
6 |
7 | However, for a more hands-on approach, you can always apply the Terraform configurations manually for a do-it-yourself setup.
8 |
9 | For detailed information on the deployment process, infrastructure, and CI/CD pipelines, please refer to the official documentation:
10 |
11 | **[Agent Starter Pack Deployment Guide](https://googlecloudplatform.github.io/agent-starter-pack/guide/deployment.html)**
--------------------------------------------------------------------------------
/agent_starter_pack/frontends/adk_live_react/frontend/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2024 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | ///
18 |
--------------------------------------------------------------------------------
/agent_starter_pack/base_template/deployment/terraform/dev/vars/env.tfvars:
--------------------------------------------------------------------------------
1 | # Project name used for resource naming
2 | project_name = "{{ cookiecutter.project_name | replace('_', '-') }}"
3 |
4 | # Your Dev Google Cloud project id
5 | dev_project_id = "your-dev-project-id"
6 |
7 | # The Google Cloud region you will use to deploy the infrastructure
8 | region = "us-central1"
9 |
10 | {%- if cookiecutter.data_ingestion %}
11 | {%- if cookiecutter.datastore_type == "vertex_ai_search" %}
12 | # The value can only be one of "global", "us" and "eu".
13 | data_store_region = "us"
14 | {%- elif cookiecutter.datastore_type == "vertex_ai_vector_search" %}
15 | vector_search_shard_size = "SHARD_SIZE_SMALL"
16 | vector_search_machine_type = "e2-standard-2"
17 | vector_search_min_replica_count = 1
18 | vector_search_max_replica_count = 1
19 | {%- endif %}
20 | {%- endif %}
21 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | test:
2 | uv run pytest tests
3 |
4 | test-templated-agents:
5 | uv run pytest tests/integration/test_templated_patterns.py
6 |
7 | test-e2e:
8 | set -a && . tests/cicd/.env && set +a && uv run pytest tests/cicd/test_e2e_deployment.py -v
9 |
10 | generate-lock:
11 | uv run python -m agent_starter_pack.utils.generate_locks
12 |
13 | lint:
14 | uv sync --dev --extra lint
15 | uv run ruff check . --config pyproject.toml --diff
16 | uv run ruff format . --check --config pyproject.toml --diff
17 | uv run mypy --config-file pyproject.toml ./agent_starter_pack/cli ./tests ./agent_starter_pack/frontends/streamlit
18 |
19 | lint-templated-agents:
20 | uv run tests/integration/test_template_linting.py
21 |
22 | clean:
23 | rm -rf target/*
24 |
25 | install:
26 | uv sync --dev --extra lint --frozen
27 |
28 | docs-dev:
29 | cd docs && npm install && NODE_OPTIONS="--no-warnings" npm run docs:dev
30 |
31 |
32 |
--------------------------------------------------------------------------------
/agent_starter_pack/frontends/adk_live_react/frontend/src/hooks/use-media-stream-mux.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2024 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | export type UseMediaStreamResult = {
18 | type: "webcam" | "screen";
19 | start: () => Promise;
20 | stop: () => void;
21 | isStreaming: boolean;
22 | stream: MediaStream | null;
23 | };
24 |
--------------------------------------------------------------------------------
/agent_starter_pack/resources/idx/idx-template.nix:
--------------------------------------------------------------------------------
1 |
2 | # No user-configurable parameters
3 | # Accept additional arguments to this template corresponding to template
4 | # parameter IDs
5 | { pkgs, agent_name ? "", google_cloud_project_id ? "", ... }: {
6 | # Shell script that produces the final environment
7 | bootstrap = ''
8 | # Copy the folder containing the `idx-template` files to the final
9 | # project folder for the new workspace. ${./.} inserts the directory
10 | # of the checked-out Git folder containing this template.
11 | cp -rf ${./.} "$out"
12 |
13 | # Set some permissions
14 | chmod -R +w "$out"
15 |
16 | # Create .env file with the parameter values
17 | cat > "$out/.env" << EOF
18 | WS_NAME=$WS_NAME
19 | EOF
20 |
21 | # Remove the template files themselves and any connection to the template's
22 | # Git repository
23 | rm -rf "$out/.git" "$out/idx-template".{nix,json}
24 | '';
25 | }
--------------------------------------------------------------------------------
/docs/cli/list.md:
--------------------------------------------------------------------------------
1 | # list
2 |
3 | List available agents and templates.
4 |
5 | ## Usage
6 |
7 | ```bash
8 | uvx agent-starter-pack list [OPTIONS]
9 | ```
10 |
11 | ## Options
12 |
13 | - `--source URL` - List templates from a specific repository
14 | - `--adk` - List official ADK samples
15 |
16 | ## Examples
17 |
18 | ```bash
19 | # List built-in agents
20 | uvx agent-starter-pack list
21 |
22 | # List ADK samples
23 | uvx agent-starter-pack list --adk
24 |
25 | # List templates from repository
26 | uvx agent-starter-pack list --source https://github.com/user/templates
27 | ```
28 |
29 | ## Notes
30 |
31 | Only templates with `[tool.agent-starter-pack]` configuration in `pyproject.toml` appear in listings. Templates without this configuration still work with `create` but aren't discoverable.
32 |
33 | ## Related
34 |
35 | - [`create`](./create.md) - Create agents from templates
36 | - [Remote Templates](../remote-templates/) - Template documentation
--------------------------------------------------------------------------------
/tests/fixtures/makefile_hashes.json:
--------------------------------------------------------------------------------
1 | {
2 | "adk_base_agent_engine_no_data": "d76c4fc040b90d51d76b2fc9dbd87bb7847aaf20b34ca937ab5e9abfbba919b9",
3 | "adk_base_cloud_run_no_data": "8b0ea9af5af817c5beb4956d9e49340f4886c634f77e0e8eee7bf82bfb8334b1",
4 | "adk_live_agent_engine": "8f06eddcaf097543eb8df6a39e22fd435f9e53ffc007f321add49e25822779f6",
5 | "adk_live_cloud_run": "789fbc07ec267d86f7e779ba4229930b6bc3e243871e5bf3ee32f497503bc552",
6 | "agent_with_agent_garden": "e08b4fd290f1f83828b48a8f663d75e8fa3745a05c2125f9d746b8eea77b7c1f",
7 | "agent_with_custom_commands": "02b5764b75be952a06abfbb8a4e15cdf6a671652f290f9ffb2994dc9aa9382ff",
8 | "agentic_rag_cloud_run_vector_search": "ec10406d7bf56d6dc253cbce8254ee33c923f369d04f406227dc5ca401564aad",
9 | "agentic_rag_cloud_run_vertex_search": "83edd4467bff3418f619c2fcb0b449646a8a5dd2aea85c60075052f8c837e0a6",
10 | "langgraph_cloud_run_no_data": "c690f5792208e6834dd389ab448784819ca97405d01a824b4534ab256e3f1c6a"
11 | }
--------------------------------------------------------------------------------
/agent_starter_pack/agents/adk_base/README.md:
--------------------------------------------------------------------------------
1 | # ADK: Minimal Agent Example
2 |
3 |
4 |
5 | A basic agent built using the **[Google Agent Development Kit (ADK)](https://google.github.io/adk-docs/)**. This example demonstrates core ADK concepts like agent creation and tool integration in a minimal setup.
6 |
7 | This agent uses the `gemini-2.5-flash` model and is equipped with two simple tools:
8 | * `get_weather`: Simulates fetching weather (hardcoded for SF).
9 | * `get_current_time`: Simulates fetching the time (hardcoded for SF).
10 |
11 | ## Additional Resources
12 |
13 | - **ADK Samples**: Explore more examples and use cases in the [official ADK Samples Repository](https://github.com/google/adk-samples)
14 | - **ADK Documentation**: Learn more about ADK concepts and capabilities in the [official documentation](https://google.github.io/adk-docs/)
15 |
--------------------------------------------------------------------------------
/agent_starter_pack/frontends/adk_live_react/frontend/src/setupTests.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2024 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
18 | // allows you to do things like:
19 | // expect(element).toHaveTextContent(/react/i)
20 | // learn more: https://github.com/testing-library/jest-dom
21 | import "@testing-library/jest-dom";
22 |
--------------------------------------------------------------------------------
/.cloudbuild/terraform/storage.tf:
--------------------------------------------------------------------------------
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 | resource "google_storage_bucket" "logs_data_bucket" {
16 | name = "${var.cicd_runner_project_id}-logs-data"
17 | location = var.region
18 | project = var.cicd_runner_project_id
19 | uniform_bucket_level_access = true
20 | force_destroy = true
21 | }
22 |
--------------------------------------------------------------------------------
/agent_starter_pack/base_template/tests/unit/test_dummy.py:
--------------------------------------------------------------------------------
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 | You can add your unit tests here.
16 | This is where you test your business logic, including agent functionality,
17 | data processing, and other core components of your application.
18 | """
19 |
20 |
21 | def test_dummy() -> None:
22 | """Placeholder - replace with real tests."""
23 | assert 1 == 1
24 |
--------------------------------------------------------------------------------
/agent_starter_pack/agents/agentic_rag/app/templates.py:
--------------------------------------------------------------------------------
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 | from langchain_core.prompts import (
16 | PromptTemplate,
17 | )
18 |
19 | format_docs = PromptTemplate.from_template(
20 | """## Context provided:
21 | {% for doc in docs%}
22 |
23 | {{ doc.page_content | safe }}
24 |
25 | {% endfor %}
26 | """,
27 | template_format="jinja2",
28 | )
29 |
--------------------------------------------------------------------------------
/agent_starter_pack/frontends/adk_live_react/frontend/src/App.test.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2024 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React from 'react';
18 | import { render, screen } from '@testing-library/react';
19 | import App from './App';
20 |
21 | test('renders learn react link', () => {
22 | render();
23 | const linkElement = screen.getByText(/learn react/i);
24 | expect(linkElement).toBeInTheDocument();
25 | });
26 |
--------------------------------------------------------------------------------
/agent_starter_pack/agents/adk_base/.template/templateconfig.yaml:
--------------------------------------------------------------------------------
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 base ReAct agent built with Google's Agent Development Kit (ADK)"
16 | example_question: "What's the weather in San Francisco?"
17 | settings:
18 | requires_data_ingestion: false
19 | requires_session: true
20 | deployment_targets: ["agent_engine", "cloud_run"]
21 | extra_dependencies: ["google-adk>=1.15.0,<2.0.0"]
22 | tags: ["adk"]
23 | frontend_type: "None"
24 |
25 |
--------------------------------------------------------------------------------
/agent_starter_pack/base_template/deployment/terraform/dev/providers.tf:
--------------------------------------------------------------------------------
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 | terraform {
16 | required_version = ">= 1.0.0"
17 | required_providers {
18 | google = {
19 | source = "hashicorp/google"
20 | version = "< 7.0.0"
21 | }
22 | }
23 | }
24 |
25 | provider "google" {
26 | alias = "dev_billing_override"
27 | billing_project = var.dev_project_id
28 | region = var.region
29 | user_project_override = true
30 | }
31 |
--------------------------------------------------------------------------------
/agent_starter_pack/resources/containers/data_processing/Dockerfile:
--------------------------------------------------------------------------------
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 | FROM python:3.11-slim
16 |
17 | RUN pip install --no-cache-dir \
18 | "bigframes==1.36.0" \
19 | "langchain==0.3.18" \
20 | "markdownify==0.14.1" \
21 | "swifter==1.4.0" \
22 | "google-cloud-aiplatform>=1.80.0" \
23 | "kfp>=1.4.0" \
24 | "google-cloud-discoveryengine==0.13.6" \
25 | "backoff==2.2.1" \
26 | "google-cloud-pipeline-components==2.19.0" \
27 | "langchain-google-vertexai==2.0.13"
28 |
--------------------------------------------------------------------------------
/agent_starter_pack/frontends/adk_live_react/frontend/src/index.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2025 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | body {
18 | margin: 0;
19 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
20 | Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
21 | -webkit-font-smoothing: antialiased;
22 | -moz-osx-font-smoothing: grayscale;
23 | }
24 |
25 | code {
26 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
27 | monospace;
28 | }
29 |
--------------------------------------------------------------------------------
/.cloudbuild/terraform/apis.tf:
--------------------------------------------------------------------------------
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 | # Enable Cloud Resource Manager API for each project in e2e_test_project_mapping
16 | resource "google_project_service" "cloud_resource_manager_api" {
17 | for_each = {
18 | "dev" = var.e2e_test_project_mapping.dev
19 | "staging" = var.e2e_test_project_mapping.staging
20 | "prod" = var.e2e_test_project_mapping.prod
21 | }
22 |
23 | project = each.value
24 | service = "cloudresourcemanager.googleapis.com"
25 | disable_on_destroy = false
26 | }
27 |
--------------------------------------------------------------------------------
/.cloudbuild/ci/build_use_wheel.yaml:
--------------------------------------------------------------------------------
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 | steps:
16 | # Sync dependencies
17 | - name: "europe-west4-docker.pkg.dev/production-ai-template/starter-pack/e2e-tests"
18 | id: install-use-dependencies
19 | entrypoint: /bin/bash
20 | args:
21 | - "-c"
22 | - |
23 | uv build && pip install dist/*.whl && agent-starter-pack create my-agent-$(date +%s) -a agentic_rag -ds vertex_ai_search -d agent_engine --auto-approve
24 |
25 | logsBucket: gs://${PROJECT_ID}-logs-data/build-logs
26 | options:
27 | defaultLogsBucketBehavior: REGIONAL_USER_OWNED_BUCKET
28 |
--------------------------------------------------------------------------------
/agent_starter_pack/agents/adk_live/.template/templateconfig.yaml:
--------------------------------------------------------------------------------
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: "Real-time multimodal agent with ADK and Gemini Live API for low-latency voice and video interaction."
16 | settings:
17 | requires_data_ingestion: false
18 | frontend_type: "adk_live_react"
19 | deployment_targets: ["agent_engine", "cloud_run"]
20 | extra_dependencies: ["google-adk>=1.15.0,<2.0.0", "click>=8.0.0,<9.0.0", "uvicorn>=0.18.0,<1.0.0", "fastapi>=0.75.0,<1.0.0", "backoff>=2.0.0,<3.0.0"]
21 | tags: ["adk", "adk_live"]
22 | example_question: "What's the weather in San Francisco?"
23 |
--------------------------------------------------------------------------------
/agent_starter_pack/frontends/adk_live_react/frontend/src/reportWebVitals.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2024 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { ReportHandler } from "web-vitals";
18 |
19 | const reportWebVitals = (onPerfEntry?: ReportHandler) => {
20 | if (onPerfEntry && onPerfEntry instanceof Function) {
21 | import("web-vitals").then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
22 | getCLS(onPerfEntry);
23 | getFID(onPerfEntry);
24 | getFCP(onPerfEntry);
25 | getLCP(onPerfEntry);
26 | getTTFB(onPerfEntry);
27 | });
28 | }
29 | };
30 |
31 | export default reportWebVitals;
32 |
--------------------------------------------------------------------------------
/agent_starter_pack/agents/crewai_coding_crew/.template/templateconfig.yaml:
--------------------------------------------------------------------------------
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 multi-agent system implemented with CrewAI created to support coding activities"
16 | settings:
17 | requires_data_ingestion: false
18 | deployment_targets: ["agent_engine", "cloud_run"]
19 | extra_dependencies: [
20 | "langchain-google-vertexai~=2.0.22",
21 | "langchain~=0.3.14",
22 | "langchain-community~=0.3.17",
23 | "langchain-openai~=0.3.5",
24 | "langgraph~=0.6.2",
25 | "crewai~=0.152.0"
26 | ]
27 | example_question: "How can I implement a function to sort a list in Python?"
28 |
--------------------------------------------------------------------------------
/agent_starter_pack/cli/utils/datastores.py:
--------------------------------------------------------------------------------
1 | """Datastore types and descriptions for data ingestion."""
2 |
3 | # Dictionary mapping datastore types to their descriptions
4 | DATASTORES = {
5 | "vertex_ai_search": {
6 | "name": "Vertex AI Search",
7 | "description": "Managed, serverless document store that enables Google-quality search and RAG for generative AI.",
8 | },
9 | "vertex_ai_vector_search": {
10 | "name": "Vertex AI Vector Search",
11 | "description": "Scalable vector search engine for building search, recommendation systems, and generative AI applications. Based on ScaNN algorithm.",
12 | },
13 | }
14 |
15 | DATASTORE_TYPES = list(DATASTORES.keys())
16 |
17 |
18 | def get_datastore_info(datastore_type: str) -> dict:
19 | """Get information about a datastore type.
20 |
21 | Args:
22 | datastore_type: The datastore type key
23 |
24 | Returns:
25 | Dictionary with datastore information
26 |
27 | Raises:
28 | ValueError: If the datastore type is not valid
29 | """
30 | if datastore_type not in DATASTORES:
31 | raise ValueError(f"Invalid datastore type: {datastore_type}")
32 | return DATASTORES[datastore_type]
33 |
--------------------------------------------------------------------------------
/agent_starter_pack/agents/langgraph_base_react/.template/templateconfig.yaml:
--------------------------------------------------------------------------------
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: "An agent implementing a base ReAct agent using LangGraph"
16 | settings:
17 | requires_data_ingestion: false
18 | deployment_targets: ["agent_engine", "cloud_run"]
19 | extra_dependencies: [
20 | "langchain-google-vertexai~=2.0.7",
21 | "langchain~=0.3.14",
22 | "langgraph~=0.6.2",
23 | "langchain-google-vertexai~=2.0.22",
24 | "langchain~=0.3.14",
25 | "langchain-community~=0.3.17",
26 | "langchain-openai~=0.3.5",
27 | ]
28 | example_question: "What's the weather in San Francisco?"
29 |
--------------------------------------------------------------------------------
/agent_starter_pack/frontends/streamlit/frontend/style/app_markdown.py:
--------------------------------------------------------------------------------
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 | MARKDOWN_STR = """
16 |
37 | """
38 |
--------------------------------------------------------------------------------
/.cloudbuild/ci/test.yaml:
--------------------------------------------------------------------------------
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 | steps:
16 | # Sync dependencies
17 | - name: "europe-west4-docker.pkg.dev/production-ai-template/starter-pack/e2e-tests"
18 | id: install-dependencies
19 | entrypoint: /bin/bash
20 | args:
21 | - "-c"
22 | - |
23 | uv sync --dev --locked
24 |
25 | # Run unit tests using pytest
26 | - name: "europe-west4-docker.pkg.dev/production-ai-template/starter-pack/e2e-tests"
27 | id: unit-tests
28 | entrypoint: /bin/bash
29 | args:
30 | - "-c"
31 | - |
32 | uv run pytest tests
33 |
34 |
35 | logsBucket: gs://${PROJECT_ID}-logs-data/build-logs
36 | options:
37 | defaultLogsBucketBehavior: REGIONAL_USER_OWNED_BUCKET
38 |
--------------------------------------------------------------------------------
/agent_starter_pack/frontends/adk_live_react/frontend/src/index.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2024 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React from 'react';
18 | import ReactDOM from 'react-dom/client';
19 | import './index.css';
20 | import App from './App';
21 | import reportWebVitals from './reportWebVitals';
22 |
23 | const root = ReactDOM.createRoot(
24 | document.getElementById('root') as HTMLElement
25 | );
26 | root.render(
27 |
28 |
29 |
30 | );
31 |
32 | // If you want to start measuring performance in your app, pass a function
33 | // to log results (for example: reportWebVitals(console.log))
34 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
35 | reportWebVitals();
36 |
--------------------------------------------------------------------------------
/.cloudbuild/ci/test_makefile.yaml:
--------------------------------------------------------------------------------
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 | steps:
16 | # Sync dependencies
17 | - name: "europe-west4-docker.pkg.dev/production-ai-template/starter-pack/e2e-tests"
18 | id: install-dependencies
19 | entrypoint: /bin/bash
20 | args:
21 | - "-c"
22 | - |
23 | uv sync --locked
24 |
25 | # Run unit tests using pytest
26 | - name: "europe-west4-docker.pkg.dev/production-ai-template/starter-pack/e2e-tests"
27 | id: test-templated-agents
28 | entrypoint: /bin/bash
29 | args:
30 | - "-c"
31 | - |
32 | uv run pytest tests/integration/test_makefile_usability.py
33 |
34 | logsBucket: gs://${PROJECT_ID}-logs-data/build-logs
35 | options:
36 | defaultLogsBucketBehavior: REGIONAL_USER_OWNED_BUCKET
37 |
--------------------------------------------------------------------------------
/.cloudbuild/ci/test_remote_template.yaml:
--------------------------------------------------------------------------------
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 | steps:
16 | # Sync dependencies
17 | - name: "europe-west4-docker.pkg.dev/production-ai-template/starter-pack/e2e-tests"
18 | id: install-dependencies
19 | entrypoint: /bin/bash
20 | args:
21 | - "-c"
22 | - |
23 | uv sync --locked
24 |
25 | # Run unit tests using pytest
26 | - name: "europe-west4-docker.pkg.dev/production-ai-template/starter-pack/e2e-tests"
27 | id: test-templated-agents
28 | entrypoint: /bin/bash
29 | args:
30 | - "-c"
31 | - |
32 | uv run pytest tests/integration/test_remote_templating.py
33 |
34 | logsBucket: gs://${PROJECT_ID}-logs-data/build-logs
35 | options:
36 | defaultLogsBucketBehavior: REGIONAL_USER_OWNED_BUCKET
37 |
--------------------------------------------------------------------------------
/agent_starter_pack/agents/langgraph_base_react/app/agent.py:
--------------------------------------------------------------------------------
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 langchain_google_vertexai import ChatVertexAI
17 | from langgraph.prebuilt import create_react_agent
18 |
19 | LOCATION = "global"
20 | LLM = "gemini-2.5-flash"
21 |
22 | llm = ChatVertexAI(model=LLM, location=LOCATION, temperature=0)
23 |
24 |
25 | def get_weather(query: str) -> str:
26 | """Simulates a web search. Use it get information on weather"""
27 | if "sf" in query.lower() or "san francisco" in query.lower():
28 | return "It's 60 degrees and foggy."
29 | return "It's 90 degrees and sunny."
30 |
31 |
32 | agent = create_react_agent(
33 | model=llm, tools=[get_weather], prompt="You are a helpful assistant"
34 | )
35 |
--------------------------------------------------------------------------------
/agent_starter_pack/agents/crewai_coding_crew/app/crew/config/agents.yaml:
--------------------------------------------------------------------------------
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 | senior_engineer_agent:
16 | role: >
17 | Senior Software Engineer
18 |
19 |
20 | goal: >
21 | Create software as needed
22 |
23 |
24 | backstory: >
25 | You are a Senior Software Engineer at a leading tech company. You are an expert Python programmer and do your best to produce perfect code.
26 |
27 |
28 | chief_qa_engineer_agent:
29 | role: >
30 | Chief Software Quality Control Engineer
31 |
32 |
33 | goal: >
34 | Ensure that the code does the job that it is supposed to do and that it is error free.
35 |
36 |
37 | backstory: >
38 | You feel that programmers always do only half the job, so you are super dedicate to make high quality code.
39 |
40 |
--------------------------------------------------------------------------------
/.cloudbuild/ci/test_pipeline_parity.yaml:
--------------------------------------------------------------------------------
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 | steps:
16 | # Sync dependencies
17 | - name: "europe-west4-docker.pkg.dev/production-ai-template/starter-pack/e2e-tests"
18 | id: install-dependencies
19 | entrypoint: /bin/bash
20 | args:
21 | - "-c"
22 | - |
23 | uv sync --dev --locked
24 |
25 | # Run pipeline parity tests
26 | - name: "europe-west4-docker.pkg.dev/production-ai-template/starter-pack/e2e-tests"
27 | id: pipeline-parity-tests
28 | entrypoint: /bin/bash
29 | args:
30 | - "-c"
31 | - |
32 | uv run pytest tests/integration/test_pipeline_parity.py -v
33 |
34 |
35 | logsBucket: gs://${PROJECT_ID}-logs-data/build-logs
36 | options:
37 | defaultLogsBucketBehavior: REGIONAL_USER_OWNED_BUCKET
38 |
--------------------------------------------------------------------------------
/agent_starter_pack/frontends/adk_live_react/frontend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "multimodal-live-api-web-console",
3 | "version": "0.1.0",
4 | "dependencies": {
5 | "classnames": "^2.5.1",
6 | "eventemitter3": "^5.0.1",
7 | "lodash": "^4.17.21",
8 | "react": "^18.3.1",
9 | "react-dom": "^18.3.1",
10 | "react-icons": "^5.3.0",
11 | "react-scripts": "5.0.1",
12 | "react-select": "^5.8.3",
13 | "sass": "^1.80.6",
14 | "web-vitals": "^2.1.4",
15 | "zustand": "^5.0.1"
16 | },
17 | "scripts": {
18 | "start": "react-scripts start",
19 | "build": "react-scripts build",
20 | "test": "react-scripts test",
21 | "eject": "react-scripts eject"
22 | },
23 | "eslintConfig": {},
24 | "browserslist": {
25 | "production": [
26 | ">0.2%",
27 | "not dead",
28 | "not op_mini all"
29 | ],
30 | "development": [
31 | "last 1 chrome version",
32 | "last 1 firefox version",
33 | "last 1 safari version"
34 | ]
35 | },
36 | "devDependencies": {
37 | "@google/generative-ai": "^0.21.0",
38 | "@testing-library/jest-dom": "^5.17.0",
39 | "@testing-library/react": "^13.4.0",
40 | "@types/lodash": "^4.17.13",
41 | "@types/react": "^18.3.12",
42 | "@types/react-dom": "^18.3.1",
43 | "typescript": "^5.6.3"
44 | },
45 | "overrides": {
46 | "typescript": "^5.6.3"
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/agent_starter_pack/base_template/deployment/terraform/providers.tf:
--------------------------------------------------------------------------------
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 |
16 | terraform {
17 | required_version = ">= 1.0.0"
18 | required_providers {
19 | google = {
20 | source = "hashicorp/google"
21 | version = "< 7.0.0"
22 | }
23 | github = {
24 | source = "integrations/github"
25 | version = "~> 6.5.0"
26 | }
27 | }
28 | }
29 |
30 | provider "google" {
31 | alias = "staging_billing_override"
32 | billing_project = var.staging_project_id
33 | region = var.region
34 | user_project_override = true
35 | }
36 |
37 | provider "google" {
38 | alias = "prod_billing_override"
39 | billing_project = var.prod_project_id
40 | region = var.region
41 | user_project_override = true
42 | }
43 |
--------------------------------------------------------------------------------
/.cloudbuild/ci/lint_templated_agents.yaml:
--------------------------------------------------------------------------------
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 | steps:
16 | # Sync dependencies
17 | - name: "europe-west4-docker.pkg.dev/production-ai-template/starter-pack/e2e-tests"
18 | id: install-dependencies
19 | entrypoint: /bin/bash
20 | args:
21 | - "-c"
22 | - |
23 | uv sync --locked
24 |
25 | # Run unit tests using pytest
26 | - name: "europe-west4-docker.pkg.dev/production-ai-template/starter-pack/e2e-tests"
27 | id: lint-templated-agents
28 | entrypoint: /bin/bash
29 | args:
30 | - "-c"
31 | - |
32 | uv run tests/integration/test_template_linting.py
33 |
34 | logsBucket: gs://${PROJECT_ID}-logs-data/build-logs
35 | options:
36 | defaultLogsBucketBehavior: REGIONAL_USER_OWNED_BUCKET
37 | env:
38 | - "_TEST_AGENT_COMBINATION=${_TEST_AGENT_COMBINATION}"
39 |
--------------------------------------------------------------------------------
/.cloudbuild/ci/test_templated_agents.yaml:
--------------------------------------------------------------------------------
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 | steps:
16 | # Sync dependencies
17 | - name: "europe-west4-docker.pkg.dev/production-ai-template/starter-pack/e2e-tests"
18 | id: install-dependencies
19 | entrypoint: /bin/bash
20 | args:
21 | - "-c"
22 | - |
23 | uv sync --locked
24 |
25 | # Run unit tests using pytest
26 | - name: "europe-west4-docker.pkg.dev/production-ai-template/starter-pack/e2e-tests"
27 | id: test-templated-agents
28 | entrypoint: /bin/bash
29 | args:
30 | - "-c"
31 | - |
32 | uv run pytest tests/integration/test_templated_patterns.py
33 |
34 | logsBucket: gs://${PROJECT_ID}-logs-data/build-logs
35 | options:
36 | defaultLogsBucketBehavior: REGIONAL_USER_OWNED_BUCKET
37 | env:
38 | - "_TEST_AGENT_COMBINATION=${_TEST_AGENT_COMBINATION}"
--------------------------------------------------------------------------------
/agent_starter_pack/agents/agentic_rag/.template/templateconfig.yaml:
--------------------------------------------------------------------------------
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: "ADK RAG agent for document retrieval and Q&A. Includes a data pipeline for ingesting and indexing documents into Vertex AI Search or Vector Search."
16 | example_question: "How to save a pandas dataframe to CSV?"
17 | settings:
18 | requires_data_ingestion: true
19 | requires_session: true
20 | deployment_targets: ["agent_engine", "cloud_run"]
21 | extra_dependencies: [
22 | "google-adk>=1.15.0,<2.0.0",
23 | "langchain-google-vertexai~=2.0.7",
24 | "langchain~=0.3.24",
25 | "langchain-core~=0.3.55",
26 | "langchain-community~=0.3.17",
27 | "langchain-openai~=0.3.5",
28 | "langchain-google-community[vertexaisearch]~=2.0.7",
29 | "Jinja2~=3.1.6",
30 | ]
31 | tags: ["adk"]
32 | frontend_type: "None"
33 |
--------------------------------------------------------------------------------
/agent_starter_pack/cli/utils/__init__.py:
--------------------------------------------------------------------------------
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 | from .datastores import DATASTORE_TYPES, get_datastore_info
16 | from .gcp import verify_credentials
17 | from .logging import handle_cli_error
18 | from .template import (
19 | get_available_agents,
20 | get_deployment_targets,
21 | get_template_path,
22 | load_template_config,
23 | process_template,
24 | prompt_datastore_selection,
25 | prompt_deployment_target,
26 | )
27 | from .version import display_update_message
28 |
29 | __all__ = [
30 | "DATASTORE_TYPES",
31 | "display_update_message",
32 | "get_available_agents",
33 | "get_datastore_info",
34 | "get_deployment_targets",
35 | "get_template_path",
36 | "handle_cli_error",
37 | "load_template_config",
38 | "process_template",
39 | "prompt_datastore_selection",
40 | "prompt_deployment_target",
41 | "verify_credentials",
42 | ]
43 |
--------------------------------------------------------------------------------
/agent_starter_pack/frontends/adk_live_react/frontend/src/utils/audioworklet-registry.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2024 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | /**
18 | * A registry to map attached worklets by their audio-context
19 | * any module using `audioContext.audioWorklet.addModule(` should register the worklet here
20 | */
21 | export type WorkletGraph = {
22 | node?: AudioWorkletNode;
23 | handlers: Array<(this: MessagePort, ev: MessageEvent) => any>;
24 | };
25 |
26 | export const registeredWorklets: Map<
27 | AudioContext,
28 | Record
29 | > = new Map();
30 |
31 | export const createWorketFromSrc = (
32 | workletName: string,
33 | workletSrc: string,
34 | ) => {
35 | const script = new Blob(
36 | [`registerProcessor("${workletName}", ${workletSrc})`],
37 | {
38 | type: "application/javascript",
39 | },
40 | );
41 |
42 | return URL.createObjectURL(script);
43 | };
44 |
--------------------------------------------------------------------------------
/.cloudbuild/terraform/variables.tf:
--------------------------------------------------------------------------------
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 | variable "cicd_runner_project_id" {
16 | type = string
17 | description = "Google Cloud Project ID where CI/CD pipelines will execute."
18 | }
19 |
20 | variable "region" {
21 | type = string
22 | description = "Google Cloud region for resource deployment."
23 | default = "us-central1"
24 | }
25 |
26 | variable "host_connection_name" {
27 | description = "Name of the host connection you created in Cloud Build"
28 | type = string
29 | }
30 |
31 | variable "repository_name" {
32 | description = "Name of the repository you'd like to connect to Cloud Build"
33 | type = string
34 | }
35 |
36 | variable "e2e_test_project_mapping" {
37 | description = "Mapping of project IDs for different environments"
38 | type = object({
39 | dev = string
40 | prod = string
41 | staging = string
42 | })
43 | }
44 |
--------------------------------------------------------------------------------
/.github/workflows/docs.yml:
--------------------------------------------------------------------------------
1 | name: Deploy Docs to GitHub Pages
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | paths:
7 | - 'docs/**'
8 | - '.github/workflows/docs.yml'
9 | workflow_dispatch:
10 |
11 | permissions:
12 | contents: read
13 | pages: write
14 | id-token: write
15 |
16 | concurrency:
17 | group: "pages"
18 | cancel-in-progress: true
19 |
20 | jobs:
21 | build:
22 | runs-on: ubuntu-latest
23 | steps:
24 | - name: Checkout
25 | uses: actions/checkout@v4
26 |
27 | - name: Setup Node.js
28 | uses: actions/setup-node@v4
29 | with:
30 | node-version: 18
31 | cache: 'npm'
32 | cache-dependency-path: docs/package-lock.json
33 |
34 | - name: Install dependencies
35 | working-directory: docs
36 | run: npm ci
37 |
38 | - name: Build VitePress site
39 | working-directory: docs
40 | run: |
41 | npm run docs:build
42 |
43 | - name: Setup Pages
44 | id: pages
45 | uses: actions/configure-pages@v5
46 |
47 | - name: Upload artifact
48 | uses: actions/upload-pages-artifact@v3
49 | with:
50 | path: docs/.vitepress/dist
51 |
52 | deploy:
53 | environment:
54 | name: github-pages
55 | url: ${{ steps.deployment.outputs.page_url }}
56 | runs-on: ubuntu-latest
57 | needs: build
58 | steps:
59 | - name: Deploy to GitHub Pages
60 | id: deployment
61 | uses: actions/deploy-pages@v4
--------------------------------------------------------------------------------
/.cloudbuild/ci/lint.yaml:
--------------------------------------------------------------------------------
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 | steps:
16 | # Sync dependencies
17 | - name: "europe-west4-docker.pkg.dev/production-ai-template/starter-pack/e2e-tests"
18 | id: install-dependencies
19 | entrypoint: /bin/bash
20 | args:
21 | - "-c"
22 | - |
23 | uv sync --dev --extra lint --locked
24 |
25 | # Run unit tests using pytest
26 | - name: "europe-west4-docker.pkg.dev/production-ai-template/starter-pack/e2e-tests"
27 | id: lint
28 | entrypoint: /bin/bash
29 | args:
30 | - "-c"
31 | - |
32 | set -e
33 | uv run ruff check . --config pyproject.toml --diff
34 | uv run ruff format . --check --config pyproject.toml --diff
35 | uv run mypy --config-file pyproject.toml ./agent_starter_pack/cli ./tests ./agent_starter_pack/frontends/streamlit
36 |
37 | logsBucket: gs://${PROJECT_ID}-logs-data/build-logs
38 | options:
39 | defaultLogsBucketBehavior: REGIONAL_USER_OWNED_BUCKET
40 |
--------------------------------------------------------------------------------
/agent_starter_pack/base_template/deployment/terraform/vars/env.tfvars:
--------------------------------------------------------------------------------
1 | # Project name used for resource naming
2 | project_name = "{{ cookiecutter.project_name | replace('_', '-') }}"
3 |
4 | # Your Production Google Cloud project id
5 | prod_project_id = "your-production-project-id"
6 |
7 | # Your Staging / Test Google Cloud project id
8 | staging_project_id = "your-staging-project-id"
9 |
10 | # Your Google Cloud project ID that will be used to host the Cloud Build pipelines.
11 | cicd_runner_project_id = "your-cicd-project-id"
12 |
13 | {%- if cookiecutter.cicd_runner == "google_cloud_build" %}
14 | # Name of the host connection you created in Cloud Build
15 | host_connection_name = "git-{{cookiecutter.project_name}}"
16 | github_pat_secret_id = "your-github_pat_secret_id"
17 | {%- endif %}
18 |
19 | repository_owner = "Your GitHub organization or username."
20 |
21 | # Name of the repository you added to Cloud Build
22 | repository_name = "{{cookiecutter.project_name}}"
23 |
24 | # The Google Cloud region you will use to deploy the infrastructure
25 | region = "us-central1"
26 |
27 | {%- if cookiecutter.data_ingestion %}
28 | pipeline_cron_schedule = "0 0 * * 0"
29 |
30 | {%- if cookiecutter.datastore_type == "vertex_ai_search" %}
31 | #The value can only be one of "global", "us" and "eu".
32 | data_store_region = "us"
33 | {%- elif cookiecutter.datastore_type == "vertex_ai_vector_search" %}
34 | vector_search_shard_size = "SHARD_SIZE_SMALL"
35 | vector_search_machine_type = "e2-standard-2"
36 | vector_search_min_replica_count = 1
37 | vector_search_max_replica_count = 1
38 | {%- endif %}
39 | {%- endif %}
40 |
--------------------------------------------------------------------------------
/docs/guide/video-tutorials.md:
--------------------------------------------------------------------------------
1 | # Video Tutorials
2 |
3 | ## Exploring Agent Starter Pack (April 2025)
4 |
5 | This comprehensive tutorial demonstrates how to rapidly deploy AI Agents using the Agent Starter Pack. We cover the architecture, detail the templates and their usage, showcase a live demo, and guide you through template-based deployment from start to finish.
6 |
7 |
8 |
9 | ## Kaggle GenAI Intensive Course Introduction (April 2025)
10 | A 6-minute introduction explaining the Agent Starter Pack and demonstrating its key features. Part of the Kaggle GenAI intensive course.
11 |
12 |
13 |
14 | ## Livestream Demo: Building 3 Agents in Under 30 Minutes (March 2025)
15 | A 120-minute livestream demonstration of the `agent-starter-pack` where we build 3 Agents in under 30 minutes!
16 |
17 |
18 |
--------------------------------------------------------------------------------
/agent_starter_pack/frontends/adk_live_react/frontend/src/contexts/LiveAPIContext.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2024 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { createContext, FC, ReactNode, useContext } from "react";
18 | import { useLiveAPI, UseLiveAPIResults } from "../hooks/use-live-api";
19 |
20 | const LiveAPIContext = createContext(undefined);
21 |
22 | export type LiveAPIProviderProps = {
23 | children: ReactNode;
24 | url?: string;
25 | userId?: string;
26 | };
27 |
28 | export const LiveAPIProvider: FC = ({
29 | url,
30 | userId,
31 | children,
32 | }) => {
33 | const liveAPI = useLiveAPI({ url, userId });
34 |
35 | return (
36 |
37 | {children}
38 |
39 | );
40 | };
41 |
42 | export const useLiveAPIContext = () => {
43 | const context = useContext(LiveAPIContext);
44 | if (!context) {
45 | throw new Error("useLiveAPIContext must be used within a LiveAPIProvider");
46 | }
47 | return context;
48 | };
49 |
--------------------------------------------------------------------------------
/agent_starter_pack/deployment_targets/cloud_run/Dockerfile:
--------------------------------------------------------------------------------
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 | FROM python:3.11-slim
16 |
17 | RUN pip install --no-cache-dir uv==0.8.13
18 |
19 | {%- if cookiecutter.is_adk_live %}
20 | # Install Node.js for frontend build
21 | RUN apt-get update && apt-get install -y \
22 | curl \
23 | && curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \
24 | && apt-get install -y nodejs \
25 | && apt-get clean \
26 | && rm -rf /var/lib/apt/lists/*
27 | {%- endif %}
28 |
29 | WORKDIR /code
30 |
31 | COPY ./pyproject.toml ./README.md ./uv.lock* ./
32 |
33 | COPY ./{{cookiecutter.agent_directory}} ./{{cookiecutter.agent_directory}}
34 |
35 | {%- if cookiecutter.is_adk_live %}
36 | # Copy and build frontend
37 | COPY ./frontend ./frontend
38 | RUN cd frontend && npm ci && npm run build
39 | {%- endif %}
40 |
41 | RUN uv sync --frozen
42 |
43 | ARG COMMIT_SHA=""
44 | ENV COMMIT_SHA=${COMMIT_SHA}
45 |
46 | EXPOSE 8080
47 |
48 | CMD ["uv", "run", "uvicorn", "{{cookiecutter.agent_directory}}.server:app", "--host", "0.0.0.0", "--port", "8080"]
--------------------------------------------------------------------------------
/tests/cli/commands/test_list.py:
--------------------------------------------------------------------------------
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 | from click.testing import CliRunner
16 | from pytest_mock import MockerFixture
17 |
18 | from agent_starter_pack.cli.commands.list import list_agents
19 |
20 |
21 | def test_list_agents_local(mocker: MockerFixture) -> None:
22 | """Test the list command with local agents."""
23 | mock_get_agents = mocker.patch(
24 | "agent_starter_pack.cli.commands.list.get_available_agents",
25 | return_value={
26 | "agent1": {"name": "Agent One", "description": "Description one"},
27 | "agent2": {"name": "Agent Two", "description": "Description two"},
28 | },
29 | )
30 |
31 | runner = CliRunner()
32 | result = runner.invoke(list_agents)
33 |
34 | assert result.exit_code == 0
35 | assert "Available built-in agents" in result.output
36 | assert "Agent One" in result.output
37 | assert "Description one" in result.output
38 | assert "Agent Two" in result.output
39 | assert "Description two" in result.output
40 | mock_get_agents.assert_called_once()
41 |
--------------------------------------------------------------------------------
/agent_starter_pack/agents/adk_live/tests/unit/test_dummy.py:
--------------------------------------------------------------------------------
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 | You can add your unit tests here.
16 | This is where you test your business logic, including agent functionality,
17 | data processing, and other core components of your application.
18 | """
19 |
20 | from app.agent import get_weather
21 |
22 |
23 | def test_get_weather_san_francisco() -> None:
24 | """Test get_weather function returns correct weather for San Francisco."""
25 | result = get_weather("What's the weather in San Francisco?")
26 | assert result == "It's 60 degrees and foggy."
27 |
28 |
29 | def test_get_weather_san_francisco_abbreviation() -> None:
30 | """Test get_weather function returns correct weather for SF abbreviation."""
31 | result = get_weather("weather in sf")
32 | assert result == "It's 60 degrees and foggy."
33 |
34 |
35 | def test_get_weather_other_location() -> None:
36 | """Test get_weather function returns default weather for other locations."""
37 | result = get_weather("What's the weather in New York?")
38 | assert result == "It's 90 degrees and sunny."
39 |
--------------------------------------------------------------------------------
/agent_starter_pack/agents/crewai_coding_crew/app/crew/config/tasks.yaml:
--------------------------------------------------------------------------------
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 | code_task:
16 | description: >
17 | You are helping writing python code. These are the instructions:
18 |
19 | Instructions ------------ {code_instructions}
20 |
21 |
22 | expected_output: >
23 | Your Final answer must be the full python code, only the python code and nothing else.
24 |
25 |
26 | evaluate_task:
27 | description: >
28 | You are helping writing python code. These are the instructions:
29 |
30 | Instructions ------------ {code_instructions}
31 |
32 | You will look over the code to insure that it is complete and does the job that it is supposed to do. You will also check for logic error, syntax errors, missing imports, variable declarations, mismatched brackets and missing test cases. If you find any issue in the code, ask the Senior Software Engineer to fix it by providing them the code and the instructions. Don't fix it yourself.
33 |
34 |
35 | expected_output: >
36 | Your Final answer must be the full python code, only the python code and nothing else.
37 |
38 |
--------------------------------------------------------------------------------
/agent_starter_pack/base_template/deployment/terraform/apis.tf:
--------------------------------------------------------------------------------
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 | resource "google_project_service" "cicd_services" {
16 | count = length(local.cicd_services)
17 | project = var.cicd_runner_project_id
18 | service = local.cicd_services[count.index]
19 | disable_on_destroy = false
20 | }
21 |
22 | resource "google_project_service" "deploy_project_services" {
23 | for_each = {
24 | for pair in setproduct(keys(local.deploy_project_ids), local.deploy_project_services) :
25 | "${pair[0]}_${replace(pair[1], ".", "_")}" => {
26 | project = local.deploy_project_ids[pair[0]]
27 | service = pair[1]
28 | }
29 | }
30 | project = each.value.project
31 | service = each.value.service
32 | disable_on_destroy = false
33 | }
34 |
35 | # Enable Cloud Resource Manager API for the CICD runner project
36 | resource "google_project_service" "cicd_cloud_resource_manager_api" {
37 | project = var.cicd_runner_project_id
38 | service = "cloudresourcemanager.googleapis.com"
39 | disable_on_destroy = false
40 | }
41 |
--------------------------------------------------------------------------------
/agent_starter_pack/frontends/adk_live_react/frontend/src/components/audio-pulse/audio-pulse.scss:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2025 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | /* stylelint-disable */
18 | .audioPulse {
19 | display: flex;
20 | width: 24px;
21 | justify-content: space-evenly;
22 | align-items: center;
23 | transition: all 0.5s;
24 |
25 | & > div {
26 | background-color: var(--Neutral-30);
27 | border-radius: 1000px;
28 | width: 4px;
29 | min-height: 4px;
30 | border-radius: 1000px;
31 | transition: height 0.1s;
32 | }
33 |
34 | &.hover > div {
35 | animation: hover 1.4s infinite alternate ease-in-out;
36 | }
37 |
38 | height: 4px;
39 | transition: opacity 0.333s;
40 |
41 | &.active {
42 | opacity: 1;
43 |
44 | & > div {
45 | background-color: var(--Neutral-80);
46 | }
47 | }
48 | }
49 |
50 | @keyframes hover {
51 | from {
52 | transform: translateY(0);
53 | }
54 |
55 | to {
56 | transform: translateY(-3.5px);
57 | }
58 | }
59 |
60 | @keyframes pulse {
61 | from {
62 | scale: 1 1;
63 | }
64 |
65 | to {
66 | scale: 1.2 1.2;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/utils/gcs.py:
--------------------------------------------------------------------------------
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 | import logging
16 |
17 | import google.cloud.storage as storage
18 | from google.api_core import exceptions
19 |
20 |
21 | def create_bucket_if_not_exists(bucket_name: str, project: str, location: str) -> None:
22 | """Creates a new bucket if it doesn't already exist.
23 |
24 | Args:
25 | bucket_name: Name of the bucket to create
26 | project: Google Cloud project ID
27 | location: Location to create the bucket in (defaults to us-central1)
28 | """
29 | storage_client = storage.Client(project=project)
30 |
31 | if bucket_name.startswith("gs://"):
32 | bucket_name = bucket_name[5:]
33 | try:
34 | storage_client.get_bucket(bucket_name)
35 | logging.info(f"Bucket {bucket_name} already exists")
36 | except exceptions.NotFound:
37 | bucket = storage_client.create_bucket(
38 | bucket_name,
39 | location=location,
40 | project=project,
41 | )
42 | logging.info(f"Created bucket {bucket.name} in {bucket.location}")
43 |
--------------------------------------------------------------------------------
/agent_starter_pack/agents/crewai_coding_crew/README.md:
--------------------------------------------------------------------------------
1 | # CrewAI Coding Crew Agent
2 |
3 | This agent combines CrewAI's collaborative AI capabilities with LangGraph to provide an interactive coding assistant that can understand requirements and generate code solutions through conversation.
4 |
5 | ## Architecture
6 |
7 | The agent implements a conversational interface using LangGraph that coordinates with a CrewAI development team. The workflow consists of:
8 |
9 | 1. A conversational agent that:
10 | - Gathers requirements through natural dialogue
11 | - Clarifies ambiguities by asking follow-up questions
12 | - Delegates actual coding work to the CrewAI development team
13 |
14 | 2. A CrewAI development team consisting of:
15 | - Senior Engineer: Responsible for implementing the code solution
16 | - Chief QA Engineer: Evaluates and validates the implemented code
17 |
18 | ## Key Features
19 |
20 | - **Interactive Requirements Gathering**: Uses LangGraph to maintain a natural conversation flow while collecting and clarifying coding requirements
21 | - **Collaborative AI Development**: Leverages CrewAI's multi-agent system to divide work between specialized AI agents
22 | - **Sequential Processing**: Tasks are processed in order, from requirements gathering to implementation to quality assurance
23 |
24 | ## How It Works
25 |
26 | 1. The LangGraph workflow manages the conversation state and determines when to:
27 | - Continue the conversation to gather more requirements
28 | - Delegate work to the CrewAI development team
29 | - Return results to the user
30 |
31 | 2. When coding is needed, the CrewAI team is activated through a custom tool that:
32 | - Passes requirements to the Senior Engineer agent
33 | - Routes the implementation to the QA Engineer for validation
34 | - Returns the final, validated solution
35 |
--------------------------------------------------------------------------------
/agent_starter_pack/base_template/deployment/terraform/dev/apis.tf:
--------------------------------------------------------------------------------
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 | locals {
16 | services = [
17 | "aiplatform.googleapis.com",
18 | "cloudbuild.googleapis.com",
19 | "run.googleapis.com",
20 | "bigquery.googleapis.com",
21 | "discoveryengine.googleapis.com",
22 | "cloudresourcemanager.googleapis.com",
23 | "iam.googleapis.com",
24 | "bigquery.googleapis.com",
25 | "serviceusage.googleapis.com",
26 | "logging.googleapis.com",
27 | "cloudtrace.googleapis.com",
28 | {%- if cookiecutter.is_adk and cookiecutter.session_type == "alloydb" %}
29 | "compute.googleapis.com",
30 | "servicenetworking.googleapis.com",
31 | "alloydb.googleapis.com",
32 | "secretmanager.googleapis.com",
33 | "dns.googleapis.com"
34 | {%- endif %}
35 | ]
36 | }
37 |
38 | resource "google_project_service" "services" {
39 | count = length(local.services)
40 | project = var.dev_project_id
41 | service = local.services[count.index]
42 | disable_on_destroy = false
43 | }
44 |
45 | resource "google_project_service_identity" "vertex_sa" {
46 | provider = google-beta
47 | project = var.dev_project_id
48 | service = "aiplatform.googleapis.com"
49 | }
50 |
--------------------------------------------------------------------------------
/agent_starter_pack/agents/adk_live/app/agent.py:
--------------------------------------------------------------------------------
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 | import os
16 |
17 | import google.auth
18 | import vertexai
19 | from google.adk.agents import Agent
20 |
21 | _, project_id = google.auth.default()
22 | os.environ.setdefault("GOOGLE_CLOUD_PROJECT", project_id)
23 | os.environ.setdefault("GOOGLE_CLOUD_LOCATION", "us-central1")
24 | os.environ.setdefault("GOOGLE_GENAI_USE_VERTEXAI", "True")
25 |
26 | vertexai.init(project=project_id, location="us-central1")
27 |
28 |
29 | def get_weather(query: str) -> str:
30 | """Simulates a web search. Use it get information on weather.
31 |
32 | Args:
33 | query: A string containing the location to get weather information for.
34 |
35 | Returns:
36 | A string with the simulated weather information for the queried location.
37 | """
38 | if "sf" in query.lower() or "san francisco" in query.lower():
39 | return "It's 60 degrees and foggy."
40 | return "It's 90 degrees and sunny."
41 |
42 |
43 | root_agent = Agent(
44 | name="root_agent",
45 | model="gemini-live-2.5-flash-preview-native-audio-09-2025",
46 | instruction="You are a helpful AI assistant designed to provide accurate and useful information.",
47 | tools=[get_weather],
48 | )
49 |
--------------------------------------------------------------------------------
/agent_starter_pack/base_template/{% if cookiecutter.cicd_runner == 'google_cloud_build' %}.cloudbuild{% else %}unused_.cloudbuild{% endif %}/pr_checks.yaml:
--------------------------------------------------------------------------------
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 | steps:
16 | # Install uv package manager and sync dependencies
17 | - name: "python:3.11-slim"
18 | id: install-dependencies
19 | entrypoint: /bin/bash
20 | args:
21 | - "-c"
22 | - |
23 | pip install uv==0.8.13 --user && uv sync --locked
24 | env:
25 | - 'PATH=/usr/local/bin:/usr/bin:~/.local/bin'
26 |
27 | # Run unit tests using pytest
28 | - name: "python:3.11-slim"
29 | id: unit-tests
30 | entrypoint: /bin/bash
31 | args:
32 | - "-c"
33 | - |
34 | uv run pytest tests/unit
35 | env:
36 | - 'PATH=/usr/local/bin:/usr/bin:~/.local/bin'
37 |
38 | # Run integration tests
39 | - name: "python:3.11-slim"
40 | id: integration-tests
41 | entrypoint: /bin/bash
42 | args:
43 | - "-c"
44 | - |
45 | uv run pytest tests/integration
46 | env:
47 | - 'PATH=/usr/local/bin:/usr/bin:~/.local/bin'
48 |
49 | logsBucket: gs://${PROJECT_ID}-{{ cookiecutter.project_name | replace('_', '-') }}-logs/build-logs
50 | options:
51 | defaultLogsBucketBehavior: REGIONAL_USER_OWNED_BUCKET
52 |
--------------------------------------------------------------------------------
/agent_starter_pack/agents/crewai_coding_crew/tests/integration/test_agent.py:
--------------------------------------------------------------------------------
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: ignore-errors
16 | from {{cookiecutter.agent_directory}}.agent import agent
17 |
18 |
19 | def test_agent_stream() -> None:
20 | """
21 | Integration test for the agent stream functionality.
22 | Tests that the agent returns valid streaming responses.
23 | """
24 | input_dict = {
25 | "messages": [
26 | {"type": "human", "content": "Hi"},
27 | {"type": "ai", "content": "Hi there!"},
28 | {"type": "human", "content": "Write a fibonacci function in python"},
29 | ]
30 | }
31 |
32 | events = [
33 | message for message, _ in agent.stream(input_dict, stream_mode="messages")
34 | ]
35 | # Verify we get a reasonable number of messages
36 | assert len(events) > 0, "Expected at least one message"
37 |
38 | # First message should be an AI message
39 | assert events[0].type == "AIMessageChunk"
40 |
41 | # At least one message should have content
42 | has_content = False
43 | for event in events:
44 | if hasattr(event, "content") and event.content:
45 | has_content = True
46 | break
47 | assert has_content, "Expected at least one message with content"
48 |
--------------------------------------------------------------------------------
/agent_starter_pack/agents/langgraph_base_react/tests/integration/test_agent.py:
--------------------------------------------------------------------------------
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: ignore-errors
16 | from {{cookiecutter.agent_directory}}.agent import agent
17 |
18 |
19 | def test_agent_stream() -> None:
20 | """
21 | Integration test for the agent stream functionality.
22 | Tests that the agent returns valid streaming responses.
23 | """
24 | input_dict = {
25 | "messages": [
26 | {"type": "human", "content": "Hi"},
27 | {"type": "ai", "content": "Hi there!"},
28 | {"type": "human", "content": "What's the weather in NY?"},
29 | ]
30 | }
31 |
32 | events = [
33 | message for message, _ in agent.stream(input_dict, stream_mode="messages")
34 | ]
35 |
36 | # Verify we get a reasonable number of messages
37 | assert len(events) > 0, "Expected at least one message"
38 |
39 | # First message should be an AI message
40 | assert events[0].type == "AIMessageChunk"
41 |
42 | # At least one message should have content
43 | has_content = False
44 | for event in events:
45 | if hasattr(event, "content") and event.content:
46 | has_content = True
47 | break
48 | assert has_content, "Expected at least one message with content"
49 |
--------------------------------------------------------------------------------
/agent_starter_pack/base_template/deployment/terraform/service_accounts.tf:
--------------------------------------------------------------------------------
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 | resource "google_service_account" "cicd_runner_sa" {
16 | account_id = "${var.project_name}-cb"
17 | display_name = "CICD Runner SA"
18 | project = var.cicd_runner_project_id
19 | depends_on = [resource.google_project_service.cicd_services, resource.google_project_service.deploy_project_services]
20 | }
21 | # Agent service account
22 | resource "google_service_account" "app_sa" {
23 | for_each = local.deploy_project_ids
24 |
25 | account_id = "${var.project_name}-app"
26 | display_name = "${var.project_name} Agent Service Account"
27 | project = each.value
28 | depends_on = [resource.google_project_service.cicd_services, resource.google_project_service.deploy_project_services]
29 | }
30 |
31 | {% if cookiecutter.data_ingestion %}
32 | # Service account to run Vertex AI pipeline
33 | resource "google_service_account" "vertexai_pipeline_app_sa" {
34 | for_each = local.deploy_project_ids
35 |
36 | account_id = "${var.project_name}-rag"
37 | display_name = "Vertex AI Pipeline app SA"
38 | project = each.value
39 | depends_on = [resource.google_project_service.cicd_services, resource.google_project_service.deploy_project_services]
40 | }
41 | {% endif %}
42 |
--------------------------------------------------------------------------------
/agent_starter_pack/base_template/deployment/terraform/locals.tf:
--------------------------------------------------------------------------------
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 | locals {
16 | cicd_services = [
17 | "cloudbuild.googleapis.com",
18 | "discoveryengine.googleapis.com",
19 | "aiplatform.googleapis.com",
20 | "serviceusage.googleapis.com",
21 | "bigquery.googleapis.com",
22 | "cloudresourcemanager.googleapis.com",
23 | "cloudtrace.googleapis.com"
24 | ]
25 |
26 | deploy_project_services = [
27 | "aiplatform.googleapis.com",
28 | "run.googleapis.com",
29 | "discoveryengine.googleapis.com",
30 | "cloudresourcemanager.googleapis.com",
31 | "iam.googleapis.com",
32 | "bigquery.googleapis.com",
33 | "serviceusage.googleapis.com",
34 | "logging.googleapis.com",
35 | "cloudtrace.googleapis.com",
36 | {%- if cookiecutter.is_adk and cookiecutter.session_type == "alloydb" %}
37 | "compute.googleapis.com",
38 | "servicenetworking.googleapis.com",
39 | "alloydb.googleapis.com",
40 | "secretmanager.googleapis.com",
41 | "dns.googleapis.com"
42 | {%- endif %}
43 | ]
44 |
45 | deploy_project_ids = {
46 | prod = var.prod_project_id
47 | staging = var.staging_project_id
48 | }
49 |
50 | all_project_ids = [
51 | var.cicd_runner_project_id,
52 | var.prod_project_id,
53 | var.staging_project_id
54 | ]
55 |
56 | }
57 |
58 |
--------------------------------------------------------------------------------
/.cloudbuild/cd/test_e2e.yaml:
--------------------------------------------------------------------------------
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 | steps:
16 | # Sync dependencies
17 | - name: "europe-west4-docker.pkg.dev/production-ai-template/starter-pack/e2e-tests"
18 | id: install-dependencies
19 | entrypoint: /bin/bash
20 | args:
21 | - "-c"
22 | - |
23 | uv sync --dev --locked
24 |
25 | # Run unit tests using pytest
26 | - name: "europe-west4-docker.pkg.dev/production-ai-template/starter-pack/e2e-tests"
27 | id: e2e-tests
28 | entrypoint: /bin/bash
29 | args:
30 | - "-c"
31 | - |
32 | GH_TOKEN=$$GITHUB_PAT uv run pytest tests/cicd/test_e2e_deployment.py -v
33 | secretEnv: ['GITHUB_PAT', 'GITHUB_APP_INSTALLATION_ID']
34 |
35 | availableSecrets:
36 | secretManager:
37 | - versionName: projects/$PROJECT_ID/secrets/github-pat/versions/latest
38 | env: 'GITHUB_PAT'
39 | - versionName: projects/$PROJECT_ID/secrets/github-app-installation-id/versions/latest
40 | env: 'GITHUB_APP_INSTALLATION_ID'
41 | logsBucket: gs://${PROJECT_ID}-logs-data/build-logs
42 | options:
43 | defaultLogsBucketBehavior: REGIONAL_USER_OWNED_BUCKET
44 | env:
45 | - "_TEST_AGENT_COMBINATION=${_TEST_AGENT_COMBINATION}"
46 | - "E2E_DEV_PROJECT=${_E2E_DEV_PROJECT}"
47 | - "E2E_STAGING_PROJECT=${_E2E_STAGING_PROJECT}"
48 | - "E2E_PROD_PROJECT=${_E2E_PROD_PROJECT}"
49 | - "E2E_CICD_PROJECT=${PROJECT_ID}"
50 | - "RUN_E2E_TESTS=1"
51 | timeout: 43200s
52 |
--------------------------------------------------------------------------------
/agent_starter_pack/frontends/adk_live_react/frontend/src/components/audio-pulse/AudioPulse.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2024 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import "./audio-pulse.scss";
18 | import React from "react";
19 | import { useEffect, useRef } from "react";
20 | import c from "classnames";
21 |
22 | const lineCount = 3;
23 |
24 | export type AudioPulseProps = {
25 | active: boolean;
26 | volume: number;
27 | hover?: boolean;
28 | };
29 |
30 | export default function AudioPulse({ active, volume, hover }: AudioPulseProps) {
31 | const lines = useRef([]);
32 |
33 | useEffect(() => {
34 | let timeout: number | null = null;
35 | const update = () => {
36 | lines.current.forEach(
37 | (line, i) =>
38 | (line.style.height = `${Math.min(
39 | 24,
40 | 4 + volume * (i === 1 ? 400 : 60),
41 | )}px`),
42 | );
43 | timeout = window.setTimeout(update, 100);
44 | };
45 |
46 | update();
47 |
48 | return () => clearTimeout((timeout as number)!);
49 | }, [volume]);
50 |
51 | return (
52 |
63 | );
64 | }
65 |
--------------------------------------------------------------------------------
/agent_starter_pack/resources/containers/e2e-tests/Dockerfile:
--------------------------------------------------------------------------------
1 | # Stage 1: Builder - Prepare APT repositories
2 | FROM ghcr.io/astral-sh/uv:python3.11-bookworm-slim AS builder
3 |
4 | # Install tools needed to add repositories
5 | RUN apt-get update && \
6 | apt-get install -y --no-install-recommends \
7 | ca-certificates \
8 | curl \
9 | gnupg && \
10 | # GitHub CLI
11 | curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | gpg --dearmor -o /usr/share/keyrings/githubcli-archive-keyring.gpg && \
12 | echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" > /etc/apt/sources.list.d/github-cli.list && \
13 | # Google Cloud SDK
14 | curl -sS https://packages.cloud.google.com/apt/doc/apt-key.gpg | gpg --dearmor -o /usr/share/keyrings/cloud.google.gpg && \
15 | echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" > /etc/apt/sources.list.d/google-cloud-sdk.list && \
16 | # Terraform
17 | curl -fsSL https://apt.releases.hashicorp.com/gpg | gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg && \
18 | echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com bookworm main" > /etc/apt/sources.list.d/hashicorp.list && \
19 | # Clean up builder stage
20 | apt-get clean && \
21 | rm -rf /var/lib/apt/lists/*
22 |
23 | # Stage 2: Final Image
24 | FROM ghcr.io/astral-sh/uv:python3.11-bookworm-slim
25 |
26 | # Copy repository configurations from the builder stage
27 | COPY --from=builder /etc/apt/sources.list.d/ /etc/apt/sources.list.d/
28 | COPY --from=builder /usr/share/keyrings/ /usr/share/keyrings/
29 |
30 | # Install the final packages
31 | RUN apt-get update && \
32 | apt-get install -y --no-install-recommends \
33 | gh \
34 | google-cloud-cli \
35 | terraform \
36 | make \
37 | nodejs \
38 | npm && \
39 | # Clean up apt cache
40 | apt-get clean && \
41 | rm -rf /var/lib/apt/lists/*
--------------------------------------------------------------------------------
/agent_starter_pack/frontends/adk_live_react/frontend/src/utils/store-logger.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2024 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { create } from "zustand";
18 | import { StreamingLog } from "../multimodal-live-types";
19 |
20 | interface StoreLoggerState {
21 | maxLogs: number;
22 | logs: StreamingLog[];
23 | log: (streamingLog: StreamingLog) => void;
24 | clearLogs: () => void;
25 | }
26 |
27 | export const useLoggerStore = create((set, get) => ({
28 | maxLogs: 500,
29 | logs: [], //mockLogs,
30 | log: ({ date, type, message }: StreamingLog) => {
31 | set((state) => {
32 | const prevLog = state.logs.at(-1);
33 | if (prevLog && prevLog.type === type && prevLog.message === message) {
34 | return {
35 | logs: [
36 | ...state.logs.slice(0, -1),
37 | {
38 | date,
39 | type,
40 | message,
41 | count: prevLog.count ? prevLog.count + 1 : 1,
42 | } as StreamingLog,
43 | ],
44 | };
45 | }
46 | return {
47 | logs: [
48 | ...state.logs.slice(-(get().maxLogs - 1)),
49 | {
50 | date,
51 | type,
52 | message,
53 | } as StreamingLog,
54 | ],
55 | };
56 | });
57 | },
58 |
59 | clearLogs: () => {
60 | console.log("clear log");
61 | set({ logs: [] });
62 | },
63 | setMaxLogs: (n: number) => set({ maxLogs: n }),
64 | }));
65 |
--------------------------------------------------------------------------------
/agent_starter_pack/frontends/adk_live_react/frontend/src/utils/worklets/vol-meter.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2024 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | const VolMeterWorket = `
18 | class VolMeter extends AudioWorkletProcessor {
19 | volume
20 | updateIntervalInMS
21 | nextUpdateFrame
22 |
23 | constructor() {
24 | super()
25 | this.volume = 0
26 | this.updateIntervalInMS = 25
27 | this.nextUpdateFrame = this.updateIntervalInMS
28 | this.port.onmessage = event => {
29 | if (event.data.updateIntervalInMS) {
30 | this.updateIntervalInMS = event.data.updateIntervalInMS
31 | }
32 | }
33 | }
34 |
35 | get intervalInFrames() {
36 | return (this.updateIntervalInMS / 1000) * sampleRate
37 | }
38 |
39 | process(inputs) {
40 | const input = inputs[0]
41 |
42 | if (input.length > 0) {
43 | const samples = input[0]
44 | let sum = 0
45 | let rms = 0
46 |
47 | for (let i = 0; i < samples.length; ++i) {
48 | sum += samples[i] * samples[i]
49 | }
50 |
51 | rms = Math.sqrt(sum / samples.length)
52 | this.volume = Math.max(rms, this.volume * 0.7)
53 |
54 | this.nextUpdateFrame -= samples.length
55 | if (this.nextUpdateFrame < 0) {
56 | this.nextUpdateFrame += this.intervalInFrames
57 | this.port.postMessage({volume: this.volume})
58 | }
59 | }
60 |
61 | return true
62 | }
63 | }`;
64 |
65 | export default VolMeterWorket;
66 |
--------------------------------------------------------------------------------
/agent_starter_pack/agents/crewai_coding_crew/app/agent.py:
--------------------------------------------------------------------------------
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 langchain_google_vertexai import ChatVertexAI
17 | from langgraph.prebuilt import create_react_agent
18 |
19 | from .crew.crew import DevCrew
20 |
21 | LOCATION = "global"
22 | LLM = "gemini-2.5-flash"
23 |
24 | llm = ChatVertexAI(model=LLM, location=LOCATION, temperature=0)
25 |
26 |
27 | def coding_tool(code_instructions: str) -> str:
28 | """Use this tool to write a python program given a set of requirements and or instructions."""
29 | inputs = {"code_instructions": code_instructions}
30 | return DevCrew().crew().kickoff(inputs=inputs)
31 |
32 |
33 | system_message = (
34 | "You are an expert Lead Software Engineer Manager.\n"
35 | "Your role is to speak to a user and understand what kind of code they need to "
36 | "build.\n"
37 | "Part of your task is therefore to gather requirements and clarifying ambiguity "
38 | "by asking followup questions. Don't ask all the questions together as the user "
39 | "has a low attention span, rather ask a question at the time.\n"
40 | "Once the problem to solve is clear, you will call your tool for writing the "
41 | "solution.\n"
42 | "Remember, you are an expert in understanding requirements but you cannot code, "
43 | "use your coding tool to generate a solution. Keep the test cases if any, they "
44 | "are useful for the user."
45 | )
46 |
47 | agent = create_react_agent(model=llm, tools=[coding_tool], prompt=system_message)
48 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Code of Conduct
2 |
3 | As contributors and maintainers of this project,
4 | and in the interest of fostering an open and welcoming community,
5 | we pledge to respect all people who contribute through reporting issues,
6 | posting feature requests, updating documentation,
7 | submitting pull requests or patches, and other activities.
8 |
9 | We are committed to making participation in this project
10 | a harassment-free experience for everyone,
11 | regardless of level of experience, gender, gender identity and expression,
12 | sexual orientation, disability, personal appearance,
13 | body size, race, ethnicity, age, religion, or nationality.
14 |
15 | Examples of unacceptable behavior by participants include:
16 |
17 | - The use of sexualized language or imagery
18 | - Personal attacks
19 | - Trolling or insulting/derogatory comments
20 | - Public or private harassment
21 | - Publishing other's private information,
22 | such as physical or electronic
23 | addresses, without explicit permission
24 | - Other unethical or unprofessional conduct.
25 |
26 | Project maintainers have the right and responsibility to remove, edit, or reject
27 | comments, commits, code, wiki edits, issues, and other contributions
28 | that are not aligned to this Code of Conduct.
29 | By adopting this Code of Conduct,
30 | project maintainers commit themselves to fairly and consistently
31 | applying these principles to every aspect of managing this project.
32 | Project maintainers who do not follow or enforce the Code of Conduct
33 | may be permanently removed from the project team.
34 |
35 | This code of conduct applies both within project spaces and in public spaces
36 | when an individual is representing the project or its community.
37 |
38 | Instances of abusive, harassing, or otherwise unacceptable behavior
39 | may be reported by opening an issue
40 | or contacting one or more of the project maintainers.
41 |
42 | This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0,
43 | available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/)
44 |
--------------------------------------------------------------------------------
/docs/guide/community-showcase.md:
--------------------------------------------------------------------------------
1 | # 🌟 Community Showcase
2 |
3 | Welcome to the Agent Starter Pack Community Showcase! This page highlights amazing projects, implementations, and creative uses of the Agent Starter Pack by our community.
4 |
5 | ## 🔍 Explore Community Projects
6 |
7 | **[Browse all community agents on GitHub →](https://github.com/search?q=Agent+generated+with+%5B%60googleCloudPlatform%2Fagent-starter-pack%60%5D&type=code)**
8 |
9 | Discover how developers are using our templates in real-world applications.
10 |
11 | ## Featured Projects
12 |
13 | ### Smart Learning Platform by [tensr](https://tensr.be/)
14 | **Repository:** [jossehuybrechts/smart-learning](https://github.com/jossehuybrechts/smart-learning)
15 | **Blog Post:** [Building a Smart Learning Platform with Google's Agent Starter Pack](https://medium.com/@tensr/9f75876bc618)
16 |
17 | An intelligent learning platform that adapts to individual learning styles and provides personalized educational content. This project demonstrates how to build a production-ready educational AI agent using the Agent Starter Pack's templates and deployment infrastructure.
18 |
19 | ### Production Monitoring Assistant by [norma](https://norma.dev/)
20 | **Repository:** [adilmoumni/prod-monitoring-assistant](https://github.com/adilmoumni/prod-monitoring-assistant)
21 | **Blog Post:** [Building an AI Agent for Production Monitoring at the Agentic Era Hackathon](https://medium.com/norma-dev/building-an-ai-agent-for-production-monitoring-at-the-agentic-era-hackathon-ffa283dd391d)
22 |
23 | An AI-powered production monitoring assistant built for the Agentic Era Hackathon. This agent helps DevOps teams monitor system health, detect anomalies, and provide intelligent insights for maintaining production environments.
24 |
25 | ---
26 |
27 | *This section will be updated regularly as we review and feature outstanding community submissions.*
28 |
29 | ## 📝 Submit Your Project
30 |
31 | Built something amazing with the Agent Starter Pack? **[Create a showcase issue](https://github.com/GoogleCloudPlatform/agent-starter-pack/issues/new?labels=showcase)** with your repository URL, project description, and unique features.
32 |
--------------------------------------------------------------------------------
/agent_starter_pack/frontends/adk_live_react/frontend/src/hooks/use-webcam.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2024 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { useState, useEffect } from "react";
18 | import { UseMediaStreamResult } from "./use-media-stream-mux";
19 |
20 | export function useWebcam(): UseMediaStreamResult {
21 | const [stream, setStream] = useState(null);
22 | const [isStreaming, setIsStreaming] = useState(false);
23 |
24 | useEffect(() => {
25 | const handleStreamEnded = () => {
26 | setIsStreaming(false);
27 | setStream(null);
28 | };
29 | if (stream) {
30 | stream
31 | .getTracks()
32 | .forEach((track) => track.addEventListener("ended", handleStreamEnded));
33 | return () => {
34 | stream
35 | .getTracks()
36 | .forEach((track) =>
37 | track.removeEventListener("ended", handleStreamEnded),
38 | );
39 | };
40 | }
41 | }, [stream]);
42 |
43 | const start = async () => {
44 | const mediaStream = await navigator.mediaDevices.getUserMedia({
45 | video: true,
46 | });
47 | setStream(mediaStream);
48 | setIsStreaming(true);
49 | return mediaStream;
50 | };
51 |
52 | const stop = () => {
53 | if (stream) {
54 | stream.getTracks().forEach((track) => track.stop());
55 | setStream(null);
56 | setIsStreaming(false);
57 | }
58 | };
59 |
60 | const result: UseMediaStreamResult = {
61 | type: "webcam",
62 | start,
63 | stop,
64 | isStreaming,
65 | stream,
66 | };
67 |
68 | return result;
69 | }
70 |
--------------------------------------------------------------------------------
/.cloudbuild/terraform/service_account.tf:
--------------------------------------------------------------------------------
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 | # Define local variables for roles
15 |
16 |
17 | locals {
18 | cicd_runner_roles = [
19 | "roles/owner",
20 | ]
21 |
22 | e2e_project_roles = [
23 | "roles/owner",
24 | ]
25 | }
26 |
27 | # Create a service account for CICD runner
28 | resource "google_service_account" "cicd_runner_sa" {
29 | project = var.cicd_runner_project_id
30 | account_id = "cicd-tests-runner-sa"
31 | display_name = "Service Account for CI/CD Pipeline Runner"
32 | description = "Used by Cloud Build to execute CI/CD pipelines"
33 | }
34 |
35 | # Grant necessary roles to the service account
36 | resource "google_project_iam_member" "cicd_runner_roles" {
37 | for_each = toset(local.cicd_runner_roles)
38 |
39 | project = var.cicd_runner_project_id
40 | role = each.key
41 | member = "serviceAccount:${google_service_account.cicd_runner_sa.email}"
42 | }
43 |
44 | # Grant permissions to the service account for each environment project
45 | resource "google_project_iam_member" "cicd_runner_e2e_project_roles" {
46 | for_each = {
47 | for idx, proj_role in flatten([
48 | for env, project_id in var.e2e_test_project_mapping : [
49 | for role in local.e2e_project_roles : {
50 | project = project_id
51 | env = env
52 | role = role
53 | }
54 | ]
55 | ]) : "${proj_role.env}-${proj_role.role}" => proj_role
56 | }
57 |
58 | project = each.value.project
59 | role = each.value.role
60 | member = "serviceAccount:${google_service_account.cicd_runner_sa.email}"
61 | }
62 |
--------------------------------------------------------------------------------
/agent_starter_pack/agents/adk_live/README.md:
--------------------------------------------------------------------------------
1 | # ADK Live Agent
2 |
3 | Real-time conversational agent built with Google ADK and Gemini's live audio model. Supports audio, video, and text interactions with native tool calling.
4 |
5 | 
6 |
7 | **Key components:**
8 |
9 | - **Python Backend** (in `app/` folder): ADK-powered agent using Gemini's live audio model with native tool calling and deployment support for Cloud Run and Agent Engine
10 |
11 | - **React Frontend** (in `frontend/` folder): Web console for interacting with the live agent via audio, video, and text
12 |
13 | 
14 |
15 | Once running, click the play button to connect and interact with the agent. Try asking "What's the weather like in San Francisco?" to see tool calling in action.
16 |
17 | ## Additional Resources for Multimodal Live API
18 |
19 | Explore these resources to learn more about the Multimodal Live API and see examples of its usage:
20 |
21 | - [Project Pastra](https://github.com/heiko-hotz/gemini-multimodal-live-dev-guide/tree/main): a comprehensive developer guide for the Gemini Multimodal Live API.
22 | - [Google Cloud Multimodal Live API demos and samples](https://github.com/GoogleCloudPlatform/generative-ai/tree/main/gemini/multimodal-live-api): Collection of code samples and demo applications leveraging multimodal live API in Vertex AI
23 | - [Gemini 2 Cookbook](https://github.com/google-gemini/cookbook/tree/main/gemini-2): Practical examples and tutorials for working with Gemini 2
24 | - [Multimodal Live API Web Console](https://github.com/google-gemini/multimodal-live-api-web-console): Interactive React-based web interface for testing and experimenting with Gemini Multimodal Live API.
25 |
26 | ## Current Status & Future Work
27 |
28 | This pattern is under active development. Key areas planned for future enhancement include:
29 |
30 | * **Observability:** Implementing comprehensive monitoring and tracing features.
31 | * **Load Testing:** Integrating load testing capabilities.
32 |
--------------------------------------------------------------------------------
/agent_starter_pack/cli/main.py:
--------------------------------------------------------------------------------
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 | import importlib.metadata
16 | import sys
17 |
18 | import click
19 | from rich.console import Console
20 |
21 | from .commands.create import create
22 | from .commands.enhance import enhance
23 | from .commands.list import list_agents
24 | from .commands.setup_cicd import setup_cicd
25 | from .utils import display_update_message
26 |
27 | console = Console()
28 |
29 |
30 | def print_version(ctx: click.Context, param: click.Parameter, value: bool) -> None:
31 | if not value or ctx.resilient_parsing:
32 | return
33 | try:
34 | version_str = importlib.metadata.version("agent-starter-pack")
35 | console.print(f"GCP Agent Starter Pack CLI version: {version_str}")
36 | except importlib.metadata.PackageNotFoundError:
37 | console.print("GCP Agent Starter Pack CLI (development version)")
38 | ctx.exit()
39 |
40 |
41 | @click.group(help="Production-ready Generative AI Agent templates for Google Cloud")
42 | @click.option(
43 | "--version",
44 | "-v",
45 | is_flag=True,
46 | callback=print_version,
47 | expose_value=False,
48 | is_eager=True,
49 | help="Show the version and exit.",
50 | )
51 | def cli() -> None:
52 | # Check for updates at startup (skip if --agent-garden or -ag is used)
53 | if "--agent-garden" not in sys.argv and "-ag" not in sys.argv:
54 | display_update_message()
55 |
56 |
57 | # Register commands
58 | cli.add_command(create)
59 | cli.add_command(enhance)
60 | cli.add_command(setup_cicd)
61 | cli.add_command(list_agents, name="list")
62 |
63 |
64 | if __name__ == "__main__":
65 | cli()
66 |
--------------------------------------------------------------------------------
/agent_starter_pack/agents/adk_base/tests/integration/test_agent.py:
--------------------------------------------------------------------------------
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 {{cookiecutter.agent_directory}}.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"
59 |
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: home
3 | title: Home
4 |
5 | hero:
6 | name: Agent Starter Pack
7 | text: Production-Ready Agents on Google Cloud, faster
8 | tagline: Go from idea to deployment faster with pre-built templates & tools.
9 | image:
10 | src: https://github.com/GoogleCloudPlatform/agent-starter-pack/blob/main/docs/images/logo.png?raw=true
11 | alt: Agent Starter Pack Logo
12 | actions:
13 | - theme: brand
14 | text: Get Started Guide
15 | link: /guide/getting-started
16 | - theme: alt
17 | text: Development Guide
18 | link: /guide/development-guide
19 | - theme: alt
20 | text: Watch Demo Video
21 | link: https://www.youtube.com/watch?v=9zqwym-N3lg
22 |
23 | features:
24 | - icon: ⚡️
25 | title: Launch Quickly
26 | details: Start fast with pre-built agent templates (ReAct, RAG, multi-agent, Live Multimodal API) implementing common patterns.
27 | - icon: 🧪
28 | title: Experiment & Evaluate
29 | details: Iterate using integrated Vertex AI evaluation and an interactive testing playground.
30 | - icon: ☁️
31 | title: Deploy Confidently
32 | details: Ship reliable agents with production-ready infra (Cloud Run / Agent Engine) featuring monitoring, observability, and CI/CD.
33 | - icon: 🛠️
34 | title: Customize & Extend
35 | details: Adapt and enhance templates for your specific use case, or create your own.
36 | ---
37 |
38 | ::: tip ⭐ Like Agent Starter Pack?
39 | Help us spread the word by giving us a star on GitHub!
40 |
41 |
42 | 
43 |
44 |
45 | :::
46 |
47 | ## Quick Links
48 |
49 | - **New Users:** [Getting Started Guide](/guide/getting-started)
50 | - **Setup:** [Installation Guide](/guide/installation)
51 | - **Going Live:** [Deployment Guide](/guide/deployment)
52 | - **Explore Templates:** [Agent Templates Overview](/agents/overview)
53 | - **Community:** [Community Showcase](/guide/community-showcase)
54 | - **Command Line:** [CLI Reference](/cli/)
--------------------------------------------------------------------------------
/agent_starter_pack/agents/crewai_coding_crew/app/crew/crew.py:
--------------------------------------------------------------------------------
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="attr-defined"
16 | from typing import Any
17 |
18 | from crewai import Agent, Crew, Process, Task
19 | from crewai.project import CrewBase, agent, crew, task
20 |
21 |
22 | @CrewBase
23 | class DevCrew:
24 | """Developer crew"""
25 |
26 | agents_config: dict[str, Any]
27 | tasks_config: dict[str, Any]
28 |
29 | llm = "vertex_ai/gemini-2.0-flash-001"
30 |
31 | @agent
32 | def senior_engineer_agent(self) -> Agent:
33 | return Agent(
34 | config=self.agents_config.get("senior_engineer_agent"),
35 | allow_delegation=False,
36 | verbose=True,
37 | llm=self.llm,
38 | )
39 |
40 | @agent
41 | def chief_qa_engineer_agent(self) -> Agent:
42 | return Agent(
43 | config=self.agents_config.get("chief_qa_engineer_agent"),
44 | allow_delegation=True,
45 | verbose=True,
46 | llm=self.llm,
47 | )
48 |
49 | @task
50 | def code_task(self) -> Task:
51 | return Task(
52 | config=self.tasks_config.get("code_task"),
53 | agent=self.senior_engineer_agent(),
54 | )
55 |
56 | @task
57 | def evaluate_task(self) -> Task:
58 | return Task(
59 | config=self.tasks_config.get("evaluate_task"),
60 | agent=self.chief_qa_engineer_agent(),
61 | )
62 |
63 | @crew
64 | def crew(self) -> Crew:
65 | """Creates the Dev Crew"""
66 | return Crew(
67 | agents=self.agents,
68 | tasks=self.tasks,
69 | process=Process.sequential,
70 | verbose=True,
71 | )
72 |
--------------------------------------------------------------------------------
/agent_starter_pack/frontends/adk_live_react/frontend/src/hooks/use-screen-capture.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2024 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { useState, useEffect } from "react";
18 | import { UseMediaStreamResult } from "./use-media-stream-mux";
19 |
20 | export function useScreenCapture(): UseMediaStreamResult {
21 | const [stream, setStream] = useState(null);
22 | const [isStreaming, setIsStreaming] = useState(false);
23 |
24 | useEffect(() => {
25 | const handleStreamEnded = () => {
26 | setIsStreaming(false);
27 | setStream(null);
28 | };
29 | if (stream) {
30 | stream
31 | .getTracks()
32 | .forEach((track) => track.addEventListener("ended", handleStreamEnded));
33 | return () => {
34 | stream
35 | .getTracks()
36 | .forEach((track) =>
37 | track.removeEventListener("ended", handleStreamEnded),
38 | );
39 | };
40 | }
41 | }, [stream]);
42 |
43 | const start = async () => {
44 | // const controller = new CaptureController();
45 | // controller.setFocusBehavior("no-focus-change");
46 | const mediaStream = await navigator.mediaDevices.getDisplayMedia({
47 | video: true,
48 | // controller
49 | });
50 | setStream(mediaStream);
51 | setIsStreaming(true);
52 | return mediaStream;
53 | };
54 |
55 | const stop = () => {
56 | if (stream) {
57 | stream.getTracks().forEach((track) => track.stop());
58 | setStream(null);
59 | setIsStreaming(false);
60 | }
61 | };
62 |
63 | const result: UseMediaStreamResult = {
64 | type: "screen",
65 | start,
66 | stop,
67 | isStreaming,
68 | stream,
69 | };
70 |
71 | return result;
72 | }
73 |
--------------------------------------------------------------------------------
/agent_starter_pack/agents/agentic_rag/README.md:
--------------------------------------------------------------------------------
1 | # Agentic RAG
2 |
3 | This agent enhances the Agent Starter Pack with a production-ready data ingestion pipeline, enriching your Retrieval Augmented Generation (RAG) applications. You will be able to ingest, process, and embed custom data, improving the relevance and context of your generated responses. You can choose between different datastore options including Vertex AI Search and Vertex AI Vector Search depending on your specific needs.
4 |
5 | The agent provides the infrastructure to create a Vertex AI Pipeline with your custom code. Because it's built on Vertex AI Pipelines, you benefit from features like scheduled runs, recurring executions, and on-demand triggers. For processing terabyte-scale data, we recommend combining Vertex AI Pipelines with data analytics tools like BigQuery or Dataflow.
6 |
7 | 
8 |
9 | ## Architecture
10 |
11 | The agent implements the following architecture:
12 |
13 | 
14 |
15 | ### Key Features
16 |
17 | - **Built on Agent Development Kit (ADK):** ADK is a flexible, modular framework for developing and deploying AI agents. It integrates with the Google ecosystem and Gemini models, supporting various LLMs and open-source AI tools, enabling both simple and complex agent architectures.
18 | - **Flexible Datastore Options:** Choose between Vertex AI Search or Vertex AI Vector Search for efficient data storage and retrieval based on your specific needs.
19 | - **Automated Data Ingestion Pipeline:** Automates the process of ingesting data from input sources.
20 | - **Custom Embeddings:** Generates embeddings using Vertex AI Embeddings and incorporates them into your data for enhanced semantic search.
21 | - **Terraform Deployment:** Ingestion pipeline is instantiated with Terraform alongside the rest of the infrastructure of the starter pack.
22 | - **CI/CD Integration:** Deployment of ingestion pipelines is added to the CD pipelines of the starter pack.
23 | - **Customizable Code:** Easily adapt and customize the code to fit your specific application needs and data sources.
24 |
--------------------------------------------------------------------------------
/agent_starter_pack/frontends/adk_live_react/frontend/src/utils/worklets/audio-processing.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2024 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | const AudioRecordingWorklet = `
18 | class AudioProcessingWorklet extends AudioWorkletProcessor {
19 |
20 | // send and clear buffer every 2048 samples,
21 | // which at 16khz is about 8 times a second
22 | buffer = new Int16Array(2048);
23 |
24 | // current write index
25 | bufferWriteIndex = 0;
26 |
27 | constructor() {
28 | super();
29 | this.hasAudio = false;
30 | }
31 |
32 | /**
33 | * @param inputs Float32Array[][] [input#][channel#][sample#] so to access first inputs 1st channel inputs[0][0]
34 | * @param outputs Float32Array[][]
35 | */
36 | process(inputs) {
37 | if (inputs[0].length) {
38 | const channel0 = inputs[0][0];
39 | this.processChunk(channel0);
40 | }
41 | return true;
42 | }
43 |
44 | sendAndClearBuffer(){
45 | this.port.postMessage({
46 | event: "chunk",
47 | data: {
48 | int16arrayBuffer: this.buffer.slice(0, this.bufferWriteIndex).buffer,
49 | },
50 | });
51 | this.bufferWriteIndex = 0;
52 | }
53 |
54 | processChunk(float32Array) {
55 | const l = float32Array.length;
56 |
57 | for (let i = 0; i < l; i++) {
58 | // convert float32 -1 to 1 to int16 -32768 to 32767
59 | const int16Value = float32Array[i] * 32768;
60 | this.buffer[this.bufferWriteIndex++] = int16Value;
61 | if(this.bufferWriteIndex >= this.buffer.length) {
62 | this.sendAndClearBuffer();
63 | }
64 | }
65 |
66 | if(this.bufferWriteIndex >= this.buffer.length) {
67 | this.sendAndClearBuffer();
68 | }
69 | }
70 | }
71 | `;
72 |
73 | export default AudioRecordingWorklet;
74 |
--------------------------------------------------------------------------------
/agent_starter_pack/resources/idx/.idx/dev.nix:
--------------------------------------------------------------------------------
1 |
2 | # To learn more about how to use Nix to configure your environment
3 | # see: https://firebase.google.com/docs/studio/customize-workspace
4 | { pkgs, ... }: {
5 | # Which nixpkgs channel to use.
6 | channel = "stable-24.11"; # or "unstable"
7 |
8 | # Use https://search.nixos.org/packages to find packages
9 | packages = [
10 | pkgs.uv
11 | pkgs.gnumake
12 | pkgs.terraform
13 | pkgs.gh
14 | ];
15 | # Sets environment variables in the workspace
16 | env = {};
17 | idx = {
18 | # Search for the extensions you want on https://open-vsx.org/ and use "publisher.id"
19 | extensions = [
20 | ];
21 | workspace = {
22 | # Runs when a workspace is first created with this `dev.nix` file
23 | onCreate = {
24 | create-venv = ''
25 | # Load environment variables from .env file if it exists
26 | source .env
27 |
28 | # Beautiful prints for gcloud setup
29 | echo ""
30 | echo "╔════════════════════════════════════════════════════════════╗"
31 | echo "║ 🔐 GCLOUD SETUP REQUIRED ║"
32 | echo "╚════════════════════════════════════════════════════════════╝"
33 | echo ""
34 | echo "📝 Before proceeding, please ensure:"
35 | echo " 1️⃣ You are logged in to gcloud"
36 | echo " 2️⃣ You have selected the correct project"
37 | echo ""
38 |
39 | auth_status=$(gcloud auth list --quiet 2>&1)
40 |
41 | echo ""
42 | echo "⚙️ We will now set the project you want to use..."
43 | gcloud config get project
44 |
45 | echo ""
46 | echo "💡 Need to setup? Run these commands:"
47 | echo " → gcloud auth login"
48 | echo " → gcloud config set project YOUR_PROJECT_ID"
49 | echo ""
50 |
51 | echo "Running agent starter pack creation..."
52 | uvx agent-starter-pack create $WS_NAME
53 | code ~/$WS_NAME/$WS_NAME/README.md
54 | exec bash
55 | '';
56 | # Open editors for the following files by default, if they exist:
57 | default.openFiles = [];
58 | };
59 | # To run something each time the workspace is (re)started, use the `onStart` hook
60 | };
61 | # Enable previews and customize configuration
62 | previews = {};
63 | };
64 | }
--------------------------------------------------------------------------------
/agent_starter_pack/base_template/{% if cookiecutter.cicd_runner == 'github_actions' %}.github{% else %}unused_github{% endif %}/workflows/pr_checks.yaml:
--------------------------------------------------------------------------------
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 | name: PR Checks
16 |
17 | on:
18 | pull_request:
19 | branches:
20 | - main
21 | paths:
22 | - '{{cookiecutter.agent_directory}}/**'
23 | - 'data_ingestion/**'
24 | - 'tests/**'
25 | - 'deployment/**'
26 | - 'uv.lock'
27 | {%- if cookiecutter.data_ingestion %}
28 | - 'data_ingestion/**'
29 | {%- endif %}
30 |
31 | jobs:
32 | test:
33 | runs-on: ubuntu-latest
34 | permissions:
35 | contents: 'read'
36 | id-token: 'write'
37 | steps:
38 | - name: Checkout code
39 | uses: actions/checkout@v4
40 |
41 | - id: 'auth'
42 | name: 'Authenticate to Google Cloud'
43 | uses: 'google-github-actions/auth@v2'
44 | with:
45 | workload_identity_provider: 'projects/{% raw %}${{ vars.GCP_PROJECT_NUMBER }}{% endraw %}/locations/global/workloadIdentityPools/{% raw %}${{ secrets.WIF_POOL_ID }}{% endraw %}/providers/{% raw %}${{ secrets.WIF_PROVIDER_ID }}{% endraw %}'
46 | service_account: '{% raw %}${{ secrets.GCP_SERVICE_ACCOUNT }}{% endraw %}'
47 | create_credentials_file: true
48 | project_id: {% raw %}${{ vars.CICD_PROJECT_ID }}{% endraw %}
49 |
50 |
51 | - name: Set up Python 3.11
52 | uses: actions/setup-python@v4
53 | with:
54 | python-version: '3.11'
55 |
56 | - name: Install uv and dependencies
57 | run: |
58 | pip install uv==0.8.13
59 | uv sync --locked
60 |
61 | - name: Run unit tests
62 | run: uv run pytest tests/unit
63 |
64 | - name: Run integration tests
65 | run: uv run pytest tests/integration
66 |
--------------------------------------------------------------------------------
/agent_starter_pack/agents/adk_base/app/agent.py:
--------------------------------------------------------------------------------
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 | import datetime
16 | import os
17 | from zoneinfo import ZoneInfo
18 |
19 | import google.auth
20 | from google.adk.agents import Agent
21 |
22 | _, project_id = google.auth.default()
23 | os.environ.setdefault("GOOGLE_CLOUD_PROJECT", project_id)
24 | os.environ.setdefault("GOOGLE_CLOUD_LOCATION", "global")
25 | os.environ.setdefault("GOOGLE_GENAI_USE_VERTEXAI", "True")
26 |
27 |
28 | def get_weather(query: str) -> str:
29 | """Simulates a web search. Use it get information on weather.
30 |
31 | Args:
32 | query: A string containing the location to get weather information for.
33 |
34 | Returns:
35 | A string with the simulated weather information for the queried location.
36 | """
37 | if "sf" in query.lower() or "san francisco" in query.lower():
38 | return "It's 60 degrees and foggy."
39 | return "It's 90 degrees and sunny."
40 |
41 |
42 | def get_current_time(query: str) -> str:
43 | """Simulates getting the current time for a city.
44 |
45 | Args:
46 | city: The name of the city to get the current time for.
47 |
48 | Returns:
49 | A string with the current time information.
50 | """
51 | if "sf" in query.lower() or "san francisco" in query.lower():
52 | tz_identifier = "America/Los_Angeles"
53 | else:
54 | return f"Sorry, I don't have timezone information for query: {query}."
55 |
56 | tz = ZoneInfo(tz_identifier)
57 | now = datetime.datetime.now(tz)
58 | return f"The current time for query {query} is {now.strftime('%Y-%m-%d %H:%M:%S %Z%z')}"
59 |
60 |
61 | root_agent = Agent(
62 | name="root_agent",
63 | model="gemini-2.5-flash",
64 | instruction="You are a helpful AI assistant designed to provide accurate and useful information.",
65 | tools=[get_weather, get_current_time],
66 | )
67 |
--------------------------------------------------------------------------------
/agent_starter_pack/agents/agentic_rag/tests/integration/test_agent.py:
--------------------------------------------------------------------------------
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 unittest.mock import MagicMock, patch
17 |
18 | from google.adk.agents.run_config import RunConfig, StreamingMode
19 | from google.adk.runners import Runner
20 | from google.adk.sessions import InMemorySessionService
21 | from google.genai import types
22 |
23 | from {{cookiecutter.agent_directory}}.agent import root_agent
24 |
25 |
26 | @patch(
27 | "{{cookiecutter.agent_directory}}.agent.retrieve_docs",
28 | return_value="dummy content",
29 | )
30 | def test_agent_stream(mock_retrieve: MagicMock) -> None:
31 | """
32 | Integration test for the agent stream functionality.
33 | Tests that the agent returns valid streaming responses.
34 | """
35 |
36 | session_service = InMemorySessionService()
37 |
38 | session = session_service.create_session_sync(user_id="test_user", app_name="test")
39 | runner = Runner(agent=root_agent, session_service=session_service, app_name="test")
40 |
41 | message = types.Content(
42 | role="user", parts=[types.Part.from_text(text="Why is the sky blue?")]
43 | )
44 |
45 | events = list(
46 | runner.run(
47 | new_message=message,
48 | user_id="test_user",
49 | session_id=session.id,
50 | run_config=RunConfig(streaming_mode=StreamingMode.SSE),
51 | )
52 | )
53 | assert len(events) > 0, "Expected at least one message"
54 |
55 | has_text_content = False
56 | for event in events:
57 | if (
58 | event.content
59 | and event.content.parts
60 | and any(part.text for part in event.content.parts)
61 | ):
62 | has_text_content = True
63 | break
64 | assert has_text_content, "Expected at least one message with text content"
65 |
--------------------------------------------------------------------------------
/agent_starter_pack/frontends/streamlit/frontend/utils/message_editing.py:
--------------------------------------------------------------------------------
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 | # fmt: off
16 |
17 | from typing import Any
18 |
19 |
20 | class MessageEditing:
21 | """Provides methods for editing, refreshing, and deleting chat messages."""
22 |
23 | @staticmethod
24 | def edit_message(st: Any, button_idx: int, message_type: str) -> None:
25 | """Edit a message in the chat history."""
26 | button_id = f"edit_box_{button_idx}"
27 | if message_type == "human":
28 | messages = st.session_state.user_chats[st.session_state["session_id"]][
29 | "messages"
30 | ]
31 | st.session_state.user_chats[st.session_state["session_id"]][
32 | "messages"
33 | ] = messages[:button_idx]
34 | st.session_state.modified_prompt = st.session_state[button_id]
35 | else:
36 | st.session_state.user_chats[st.session_state["session_id"]]["messages"][
37 | button_idx
38 | ]["content"] = st.session_state[button_id]
39 |
40 | @staticmethod
41 | def refresh_message(st: Any, button_idx: int, content: str) -> None:
42 | """Refresh a message in the chat history."""
43 | messages = st.session_state.user_chats[st.session_state["session_id"]][
44 | "messages"
45 | ]
46 | st.session_state.user_chats[st.session_state["session_id"]][
47 | "messages"
48 | ] = messages[:button_idx]
49 | st.session_state.modified_prompt = content
50 |
51 | @staticmethod
52 | def delete_message(st: Any, button_idx: int) -> None:
53 | """Delete a message from the chat history."""
54 | messages = st.session_state.user_chats[st.session_state["session_id"]][
55 | "messages"
56 | ]
57 | st.session_state.user_chats[st.session_state["session_id"]][
58 | "messages"
59 | ] = messages[:button_idx]
60 |
--------------------------------------------------------------------------------
/agent_starter_pack/frontends/adk_live_react/frontend/src/App.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2024 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { useRef, useState } from "react";
18 | import "./App.scss";
19 | import { LiveAPIProvider } from "./contexts/LiveAPIContext";
20 | import SidePanel from "./components/side-panel/SidePanel";
21 | import cn from "classnames";
22 |
23 | // In development mode (frontend on :8501), connect to backend on :8000
24 | const isDevelopment = window.location.port === '8501';
25 | const defaultHost = isDevelopment ? `${window.location.hostname}:8000` : window.location.host;
26 | const defaultUri = `${window.location.protocol === 'https:' ? 'wss:' : 'ws:'}//${defaultHost}/`;
27 |
28 | function App() {
29 | const videoRef = useRef(null);
30 | const [videoStream, setVideoStream] = useState(null);
31 | const [serverUrl, setServerUrl] = useState(defaultUri);
32 | const [userId, setUserId] = useState("user1");
33 |
34 | return (
35 |
36 |
37 |
38 |
47 |
48 |
49 |
57 |
58 |
59 |
60 |
61 |
62 | );
63 | }
64 |
65 | export default App;
66 |
--------------------------------------------------------------------------------
/docs/guide/observability.md:
--------------------------------------------------------------------------------
1 | # Monitoring and Observability
2 |
3 | 
4 |
5 | ### Trace and Log Capture
6 |
7 | Templated agents utilize [OpenTelemetry](https://opentelemetry.io/) for comprehensive observability, emitting events to Google Cloud Trace and Google Cloud Logging. Every interaction with the LLM instrumented, enabling detailed tracing of request flows throughout agents built with this framework.
8 |
9 | Leveraging the [CloudTraceSpanExporter](https://cloud.google.com/python/docs/reference/spanner/latest/opentelemetry-tracing), the framework captures and exports tracing data. To address the limitations of Cloud Trace ([256-byte attribute value limit](https://cloud.google.com/trace/docs/quotas#limits_on_spans)) and [Cloud Logging](https://cloud.google.com/logging/quotas) ([256KB log entry size](https://cloud.google.com/logging/quotas)), a custom extension of the CloudTraceSpanExporter is implemented in `app/utils/tracing.py` of the templated project.
10 |
11 | This extension enhances observability by:
12 |
13 | - Creating a corresponding Google Cloud Logging entry for every captured event.
14 | - Automatically storing event data in Google Cloud Storage when the payload exceeds 256KB.
15 |
16 | Logged payloads are associated with the original trace, ensuring seamless access from the Cloud Trace console.
17 |
18 | ### Log Router
19 |
20 | Events are forwarded to BigQuery through a [log router](https://cloud.google.com/logging/docs/routing/overview) for long-term storage and analysis. The deployment of the log router is handled via Terraform code in `deployment/terraform` in the templated project.
21 |
22 | ### Looker Studio Dashboard
23 |
24 | Once the data is written to BigQuery, it can be used to populate a [Looker Studio dashboard](https://lookerstudio.google.com/c/reporting/46b35167-b38b-4e44-bd37-701ef4307418/page/tEnnC). Use [this dashboard](https://lookerstudio.google.com/c/reporting/fa742264-4b4b-4c56-81e6-a667dd0f853f/page/tEnnC) if using non-ADK agents.
25 |
26 | This dashboard template provides a starting point for building custom visualizations on top of the captured data.
27 |
28 | ## Disclaimer
29 |
30 | **Note:** The templated agents are designed to enable *your* use-case observability in your Google Cloud Project. Google Cloud does not log, monitor, or otherwise access any data generated from the deployed resources. See the [Google Cloud Service Terms](https://cloud.google.com/terms/service-terms) for more details.
31 |
--------------------------------------------------------------------------------
/agent_starter_pack/frontends/streamlit/frontend/utils/chat_utils.py:
--------------------------------------------------------------------------------
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 | import os
16 | from pathlib import Path
17 | from typing import Any
18 |
19 | import yaml
20 |
21 | SAVED_CHAT_PATH = str(os.getcwd()) + "/.saved_chats"
22 |
23 |
24 | def clean_text(text: str) -> str:
25 | """Preprocess the input text by removing leading and trailing newlines."""
26 | if not text:
27 | return text
28 |
29 | if text.startswith("\n"):
30 | text = text[1:]
31 | if text.endswith("\n"):
32 | text = text[:-1]
33 | return text
34 |
35 |
36 | def sanitize_messages(
37 | messages: list[dict[str, str | list[dict[str, str]]]],
38 | ) -> list[dict[str, str | list[dict[str, str]]]]:
39 | """Preprocess and fix the content of messages."""
40 | for message in messages:
41 | if isinstance(message["content"], list):
42 | for part in message["content"]:
43 | if part["type"] == "text":
44 | part["text"] = clean_text(part["text"])
45 | else:
46 | message["content"] = clean_text(message["content"])
47 | return messages
48 |
49 |
50 | def save_chat(st: Any) -> None:
51 | """Save the current chat session to a YAML file."""
52 | Path(SAVED_CHAT_PATH).mkdir(parents=True, exist_ok=True)
53 | session_id = st.session_state["session_id"]
54 | session = st.session_state.user_chats[session_id]
55 | messages = session.get("messages", [])
56 | if len(messages) > 0:
57 | session["messages"] = sanitize_messages(session["messages"])
58 | filename = f"{session_id}.yaml"
59 | with open(Path(SAVED_CHAT_PATH) / filename, "w", encoding="utf-8") as file:
60 | yaml.dump(
61 | [session],
62 | file,
63 | allow_unicode=True,
64 | default_flow_style=False,
65 | encoding="utf-8",
66 | )
67 | st.toast(f"Chat saved to path: ↓ {Path(SAVED_CHAT_PATH) / filename}")
68 |
--------------------------------------------------------------------------------
/docs/remote-templates/index.md:
--------------------------------------------------------------------------------
1 | # Remote Templates
2 |
3 | Remote templates turn your agent prototype into a production-ready starter pack. A remote template is a Git repository containing your custom agent logic, dependencies, and infrastructure definitions (Terraform). The `agent-starter-pack` CLI uses it to generate a complete, deployable application by automatically adding production-grade boilerplate for testing and multi-target deployment (e.g., Cloud Run, Agent Engine).
4 |
5 | ## Choose Your Path
6 |
7 | ### 🚀 Using Remote Templates
8 | **For developers who want to use existing templates**
9 |
10 | Use any Git repository as a template to create production-ready agents instantly. Perfect for getting started quickly or using community-created templates.
11 |
12 | **[👉 Go to Using Remote Templates Guide](./using-remote-templates.md)**
13 |
14 | Quick example:
15 | ```bash
16 | uvx agent-starter-pack create my-agent -a adk@gemini-fullstack
17 | ```
18 |
19 | ---
20 |
21 | ### 🛠️ Creating Remote Templates
22 | **For developers who want to share their own templates**
23 |
24 | Package your custom agent logic, dependencies, and infrastructure into reusable templates that others can use. Perfect for sharing best practices and creating standardized agent patterns.
25 |
26 | **[👉 Go to Creating Remote Templates Guide](./creating-remote-templates.md)**
27 |
28 | Quick example:
29 | ```bash
30 | # After creating your template repository
31 | uvx agent-starter-pack create test-agent -a https://github.com/you/your-template
32 | ```
33 |
34 | ---
35 |
36 | ## Overview
37 |
38 | Remote templates work by:
39 | 1. **Fetching** template repositories from Git
40 | 2. **Version locking** - automatically uses the exact starter pack version specified by the template for guaranteed compatibility
41 | 3. **Applying** intelligent defaults based on repository structure
42 | 4. **Merging** template files with base agent infrastructure
43 | 5. **Generating** complete, production-ready agent projects
44 |
45 | Any Git repository can become a template - the system handles the complexity automatically.
46 |
47 | ## Related Documentation
48 |
49 | - **[Using Remote Templates](./using-remote-templates.md)** - Complete guide for template users
50 | - **[Creating Remote Templates](./creating-remote-templates.md)** - Complete guide for template authors
51 | - **[Template Config Reference](../guide/template-config-reference.md)** - All available configuration options
52 | - **[create CLI](../cli/create.md)** - Command line reference for creating agents
53 | - **[enhance CLI](../cli/enhance.md)** - Command line reference for enhancing projects
--------------------------------------------------------------------------------
/agent_starter_pack/utils/lock_utils.py:
--------------------------------------------------------------------------------
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 | """Utilities for managing uv lock files and dependencies."""
16 |
17 | import pathlib
18 | from pathlib import Path
19 | from typing import NamedTuple
20 |
21 | import yaml
22 |
23 |
24 | class AgentConfig(NamedTuple):
25 | """Configuration for an agent template."""
26 |
27 | targets: set[str]
28 | dependencies: list[str]
29 |
30 |
31 | def get_agent_configs(
32 | agents_dir: pathlib.Path = pathlib.Path("agent_starter_pack/agents"),
33 | ) -> dict[str, AgentConfig]:
34 | """Get all agents and their supported deployment targets.
35 |
36 | Args:
37 | agents_dir: Path to the agents directory
38 |
39 | Returns:
40 | Dictionary mapping agent names to their configuration
41 | """
42 | agent_configs = {}
43 |
44 | for agent_dir in agents_dir.iterdir():
45 | if not agent_dir.is_dir():
46 | continue
47 |
48 | config_file = agent_dir / ".template" / "templateconfig.yaml"
49 | if not config_file.exists():
50 | continue
51 |
52 | with open(config_file, encoding="utf-8") as f:
53 | config = yaml.safe_load(f)
54 |
55 | agent_name = agent_dir.name
56 | settings = config.get("settings", {})
57 |
58 | agent_configs[agent_name] = settings
59 |
60 | return agent_configs
61 |
62 |
63 | def get_lock_filename(agent_name: str, deployment_target: str) -> str:
64 | """Generate the lock filename for a given agent and deployment target.
65 |
66 | Args:
67 | agent_name: Name of the agent
68 | deployment_target: Target deployment platform
69 |
70 | Returns:
71 | Formatted lock filename
72 | """
73 | return f"uv-{agent_name}-{deployment_target}.lock"
74 |
75 |
76 | def get_lock_path(agent_name: str, deployment_target: str) -> Path:
77 | """Get the path to the appropriate lock file."""
78 | lock_filename = get_lock_filename(agent_name, deployment_target)
79 | return Path("agent_starter_pack/resources/locks") / lock_filename
80 |
--------------------------------------------------------------------------------
/tests/integration/utils.py:
--------------------------------------------------------------------------------
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 | import pathlib
16 | import subprocess
17 |
18 | from rich.console import Console
19 |
20 | console = Console()
21 |
22 |
23 | def run_command(
24 | cmd: list[str],
25 | cwd: pathlib.Path | None,
26 | message: str,
27 | stream_output: bool = True,
28 | env: dict | None = None,
29 | ) -> subprocess.CompletedProcess:
30 | """Helper function to run commands and stream output"""
31 | console.print(f"\n[bold blue]{message}...[/]")
32 | try:
33 | # Using Popen to stream output
34 | with subprocess.Popen(
35 | cmd,
36 | stdout=subprocess.PIPE,
37 | stderr=subprocess.PIPE,
38 | text=True,
39 | cwd=cwd,
40 | bufsize=1, # Line-buffered
41 | env=env,
42 | encoding="utf-8",
43 | ) as process:
44 | if stream_output:
45 | # Stream stdout
46 | if process.stdout:
47 | for line in process.stdout:
48 | console.print(line.strip())
49 |
50 | # Stream stderr
51 | if process.stderr:
52 | for line in process.stderr:
53 | console.print("[bold red]" + line.strip())
54 | else:
55 | # Consume the output but don't print it
56 | if process.stdout:
57 | for _ in process.stdout:
58 | pass
59 | if process.stderr:
60 | for _ in process.stderr:
61 | pass
62 |
63 | # Wait for the process to complete and get the return code
64 | returncode = process.wait()
65 |
66 | if returncode != 0:
67 | raise subprocess.CalledProcessError(returncode, cmd)
68 |
69 | console.print(f"[green]✓[/] {message} completed successfully")
70 | return subprocess.CompletedProcess(cmd, returncode, "", "")
71 |
72 | except subprocess.CalledProcessError:
73 | console.print(f"[bold red]Error: {message}[/]")
74 | raise
75 |
--------------------------------------------------------------------------------
/agent_starter_pack/frontends/adk_live_react/frontend/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
27 |
28 |
29 |
32 |
35 |
36 |
45 | Multimodal Live - Console
46 |
47 |
48 |
49 |
50 |
51 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/tests/test_frontend/test_utils/test_multimodal_utils.py:
--------------------------------------------------------------------------------
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 | from unittest.mock import MagicMock, patch
16 |
17 | import pytest
18 |
19 | from frontend.utils.multimodal_utils import (
20 | format_content,
21 | get_gcs_blob_mime_type,
22 | gs_uri_to_https_url,
23 | )
24 |
25 |
26 | def test_format_content_text_only() -> None:
27 | """Test formatting plain text content"""
28 | content = "Hello world"
29 | formatted = format_content(content)
30 | assert formatted == "Hello world"
31 |
32 |
33 | def test_format_content_single_image() -> None:
34 | """Test formatting content with a single image"""
35 | content = [{"type": "image_url", "image_url": {"url": "test.jpg"}}]
36 | formatted = format_content(content)
37 | assert ' None:
42 | """Test formatting content with text and images"""
43 | content = [
44 | {"type": "text", "text": "Here's an image:"},
45 | {"type": "image_url", "image_url": {"url": "test.jpg"}},
46 | ]
47 | formatted = format_content(content)
48 | assert "Here's an image:" in formatted
49 | assert ' None:
54 | """Test getting MIME type from GCS blob"""
55 | mock_blob = MagicMock()
56 | mock_blob.content_type = "image/jpeg"
57 | mock_bucket = MagicMock()
58 | mock_bucket.blob.return_value = mock_blob
59 | mock_storage_client.return_value.bucket.return_value = mock_bucket
60 |
61 | mime_type = get_gcs_blob_mime_type("gs://bucket/test.jpg")
62 | assert mime_type == "image/jpeg"
63 |
64 |
65 | def test_gs_uri_to_https_url() -> None:
66 | """Test converting GCS URI to HTTPS URL"""
67 | gs_uri = "gs://bucket/folder/file.jpg"
68 | https_url = gs_uri_to_https_url(gs_uri)
69 | assert https_url == "https://storage.mtls.cloud.google.com/bucket/folder/file.jpg"
70 |
71 |
72 | def test_gs_uri_to_https_url_invalid() -> None:
73 | """Test converting invalid GCS URI"""
74 | with pytest.raises(ValueError):
75 | gs_uri_to_https_url("invalid_uri")
76 |
--------------------------------------------------------------------------------
/agent_starter_pack/base_template/deployment/terraform/{% if cookiecutter.cicd_runner == 'github_actions' %}wif.tf{% else %}unused_wif.tf{% endif %}:
--------------------------------------------------------------------------------
1 |
2 | data "google_project" "cicd_project" {
3 | project_id = var.cicd_runner_project_id
4 | }
5 |
6 | resource "google_service_account_iam_member" "github_oidc_access" {
7 | service_account_id = resource.google_service_account.cicd_runner_sa.name
8 | role = "roles/iam.workloadIdentityUser"
9 | member = "principalSet://iam.googleapis.com/projects/${data.google_project.cicd_project.number}/locations/global/workloadIdentityPools/${google_iam_workload_identity_pool.github_pool.workload_identity_pool_id}/attribute.repository/${var.repository_owner}/${var.repository_name}"
10 | depends_on = [resource.google_project_service.cicd_services, resource.google_project_service.deploy_project_services]
11 | }
12 |
13 | # Allow the GitHub Actions principal to impersonate the CICD runner service account
14 | resource "google_service_account_iam_member" "github_sa_impersonation" {
15 | service_account_id = resource.google_service_account.cicd_runner_sa.name
16 | role = "roles/iam.serviceAccountTokenCreator"
17 | member = "principalSet://iam.googleapis.com/projects/${data.google_project.cicd_project.number}/locations/global/workloadIdentityPools/${google_iam_workload_identity_pool.github_pool.workload_identity_pool_id}/attribute.repository/${var.repository_owner}/${var.repository_name}"
18 | depends_on = [resource.google_project_service.cicd_services, resource.google_project_service.deploy_project_services]
19 | }
20 |
21 | resource "google_iam_workload_identity_pool" "github_pool" {
22 | workload_identity_pool_id = "${var.project_name}-pool"
23 | project = var.cicd_runner_project_id
24 | display_name = "GitHub Actions Pool"
25 | depends_on = [resource.google_project_service.cicd_services, resource.google_project_service.deploy_project_services]
26 | }
27 |
28 | resource "google_iam_workload_identity_pool_provider" "github_provider" {
29 | workload_identity_pool_provider_id = "${var.project_name}-oidc"
30 | project = var.cicd_runner_project_id
31 | workload_identity_pool_id = google_iam_workload_identity_pool.github_pool.workload_identity_pool_id
32 | display_name = "GitHub OIDC Provider"
33 | oidc {
34 | issuer_uri = "https://token.actions.githubusercontent.com"
35 | }
36 | attribute_mapping = {
37 | "google.subject" = "assertion.sub"
38 | "attribute.repository" = "assertion.repository"
39 | "attribute.repository_owner" = "assertion.repository_owner"
40 | }
41 | attribute_condition = "attribute.repository == '${var.repository_owner}/${var.repository_name}'"
42 | depends_on = [resource.google_project_service.cicd_services, resource.google_project_service.deploy_project_services]
43 | }
44 |
--------------------------------------------------------------------------------
/agent_starter_pack/base_template/deployment/terraform/dev/log_sinks.tf:
--------------------------------------------------------------------------------
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 | resource "google_project_iam_member" "bigquery_data_editor" {
16 |
17 | project = var.dev_project_id
18 | role = "roles/bigquery.dataEditor"
19 | member = module.log_export_to_bigquery.writer_identity
20 | }
21 |
22 | resource "google_bigquery_dataset" "feedback_dataset" {
23 | project = var.dev_project_id
24 | dataset_id = replace("${var.project_name}_feedback", "-", "_")
25 | friendly_name = "${var.project_name}_feedback"
26 | location = var.region
27 | depends_on = [resource.google_project_service.services]
28 | }
29 |
30 | resource "google_bigquery_dataset" "telemetry_logs_dataset" {
31 | project = var.dev_project_id
32 | dataset_id = replace("${var.project_name}_telemetry", "-", "_")
33 | friendly_name = "${var.project_name}_telemetry"
34 | location = var.region
35 | depends_on = [resource.google_project_service.services]
36 | }
37 |
38 | module "feedback_export_to_bigquery" {
39 | source = "terraform-google-modules/log-export/google"
40 | version = "10.0.0"
41 | log_sink_name = "${var.project_name}_feedback"
42 | parent_resource_type = "project"
43 | parent_resource_id = var.dev_project_id
44 | destination_uri = "bigquery.googleapis.com/projects/${var.dev_project_id}/datasets/${google_bigquery_dataset.feedback_dataset.dataset_id}"
45 | filter = var.feedback_logs_filter
46 | bigquery_options = { use_partitioned_tables = true }
47 | unique_writer_identity = true
48 | depends_on = [google_bigquery_dataset.feedback_dataset]
49 | }
50 |
51 | module "log_export_to_bigquery" {
52 | source = "terraform-google-modules/log-export/google"
53 | version = "10.0.0"
54 |
55 | log_sink_name = "${var.project_name}_telemetry"
56 | parent_resource_type = "project"
57 | parent_resource_id = var.dev_project_id
58 | destination_uri = "bigquery.googleapis.com/projects/${var.dev_project_id}/datasets/${google_bigquery_dataset.telemetry_logs_dataset.dataset_id}"
59 | filter = var.telemetry_logs_filter
60 | bigquery_options = { use_partitioned_tables = true }
61 | unique_writer_identity = true
62 | depends_on = [google_bigquery_dataset.telemetry_logs_dataset]
63 | }
64 |
--------------------------------------------------------------------------------
/tests/fixtures/makefile_snapshots/adk_base_agent_engine_no_data.makefile:
--------------------------------------------------------------------------------
1 | # ==============================================================================
2 | # Installation & Setup
3 | # ==============================================================================
4 |
5 | # Install dependencies using uv package manager
6 | install:
7 | @command -v uv >/dev/null 2>&1 || { echo "uv is not installed. Installing uv..."; curl -LsSf https://astral.sh/uv/0.8.13/install.sh | sh; source $HOME/.local/bin/env; }
8 | uv sync --dev
9 |
10 | # ==============================================================================
11 | # Playground Targets
12 | # ==============================================================================
13 |
14 | # Launch local dev playground
15 | playground:
16 | @echo "==============================================================================="
17 | @echo "| 🚀 Starting your agent playground... |"
18 | @echo "| |"
19 | @echo "| 💡 Try asking: What can you help me with?|"
20 | @echo "| |"
21 | @echo "| 🔍 IMPORTANT: Select the 'test_adk_base' folder to interact with your agent. |"
22 | @echo "==============================================================================="
23 | uv run adk web . --port 8501 --reload_agents
24 |
25 | # ==============================================================================
26 | # Backend Deployment Targets
27 | # ==============================================================================
28 |
29 | # Deploy the agent remotely
30 | backend:
31 | # Export dependencies to requirements file using uv export.
32 | uv export --no-hashes --no-header --no-dev --no-emit-project --no-annotate > .requirements.txt 2>/dev/null || \
33 | uv export --no-hashes --no-header --no-dev --no-emit-project > .requirements.txt && uv run test_adk_base/agent_engine_app.py
34 |
35 |
36 | # ==============================================================================
37 | # Infrastructure Setup
38 | # ==============================================================================
39 |
40 | # Set up development environment resources using Terraform
41 | setup-dev-env:
42 | PROJECT_ID=$$(gcloud config get-value project) && \
43 | (cd deployment/terraform/dev && terraform init && terraform apply --var-file vars/env.tfvars --var dev_project_id=$$PROJECT_ID --auto-approve)
44 |
45 | # ==============================================================================
46 | # Testing & Code Quality
47 | # ==============================================================================
48 |
49 | # Run unit and integration tests
50 | test:
51 | uv run pytest tests/unit && uv run pytest tests/integration
52 |
53 | # Run code quality checks (codespell, ruff, mypy)
54 | lint:
55 | uv sync --dev --extra lint
56 | uv run codespell
57 | uv run ruff check . --diff
58 | uv run ruff format . --check --diff
59 | uv run mypy .
60 |
--------------------------------------------------------------------------------
/tests/fixtures/makefile_snapshots/agent_with_custom_commands.makefile:
--------------------------------------------------------------------------------
1 | # ==============================================================================
2 | # Installation & Setup
3 | # ==============================================================================
4 |
5 | # Install dependencies using uv package manager
6 | install:
7 | @command -v uv >/dev/null 2>&1 || { echo "uv is not installed. Installing uv..."; curl -LsSf https://astral.sh/uv/0.8.13/install.sh | sh; source $HOME/.local/bin/env; }
8 | echo 'Custom install command'
9 |
10 | # ==============================================================================
11 | # Playground Targets
12 | # ==============================================================================
13 |
14 | # Launch local dev playground
15 | playground:
16 | echo 'Custom playground'
17 |
18 | # ==============================================================================
19 | # Agent-Specific Commands
20 | # ==============================================================================
21 |
22 | # Run a custom task
23 | custom-task:
24 | echo 'Running custom task'
25 |
26 | # Task with deployment-specific commands
27 | env-specific-task:
28 | echo 'Cloud Run task'
29 |
30 | # ==============================================================================
31 | # Backend Deployment Targets
32 | # ==============================================================================
33 |
34 | # Deploy the agent remotely
35 | # Usage: make backend [IAP=true] [PORT=8080] - Set IAP=true to enable Identity-Aware Proxy, PORT to specify container port
36 | backend:
37 | PROJECT_ID=$$(gcloud config get-value project) && \
38 | gcloud beta run deploy test-custom \
39 | --source . \
40 | --memory "4Gi" \
41 | --project $$PROJECT_ID \
42 | --region "us-central1" \
43 | --no-allow-unauthenticated \
44 | --no-cpu-throttling \
45 | --labels "" \
46 | --set-env-vars \
47 | "COMMIT_SHA=$(shell git rev-parse HEAD)" \
48 | $(if $(IAP),--iap) \
49 | $(if $(PORT),--port=$(PORT))
50 |
51 |
52 | # ==============================================================================
53 | # Infrastructure Setup
54 | # ==============================================================================
55 |
56 | # Set up development environment resources using Terraform
57 | setup-dev-env:
58 | PROJECT_ID=$$(gcloud config get-value project) && \
59 | (cd deployment/terraform/dev && terraform init && terraform apply --var-file vars/env.tfvars --var dev_project_id=$$PROJECT_ID --auto-approve)
60 |
61 | # ==============================================================================
62 | # Testing & Code Quality
63 | # ==============================================================================
64 |
65 | # Run unit and integration tests
66 | test:
67 | uv run pytest tests/unit && uv run pytest tests/integration
68 |
69 | # Run code quality checks (codespell, ruff, mypy)
70 | lint:
71 | uv sync --dev --extra lint
72 | uv run codespell
73 | uv run ruff check . --diff
74 | uv run ruff format . --check --diff
75 | uv run mypy .
76 |
--------------------------------------------------------------------------------
/docs/guide/troubleshooting.md:
--------------------------------------------------------------------------------
1 | # Troubleshooting
2 |
3 | This guide helps resolve common issues with the Agent Starter Pack.
4 |
5 | ## Authentication Issues
6 |
7 | For detailed information on authentication with Vertex AI, visit the [official documentation](https://cloud.google.com/vertex-ai/docs/authentication).
8 |
9 | ### "Could not find credentials" or "Could not find project" Error
10 |
11 | **Problem**: Missing credentials error with Vertex AI.
12 |
13 | **Solution**:
14 |
15 | 1. Log in to Google Cloud: `gcloud auth login --update-adc`
16 | 2. Set the correct project:
17 | ```bash
18 | gcloud config set project YOUR_PROJECT_ID
19 | gcloud auth application-default set-quota-project YOUR_PROJECT_ID
20 | ```
21 |
22 | ### Vertex AI API Not Enabled
23 |
24 | **Problem**: Operations fail because the Vertex AI API is not enabled in your project.
25 |
26 | **Solution**:
27 |
28 | 1. Enable the Vertex AI API:
29 | ```bash
30 | gcloud services enable aiplatform.googleapis.com
31 | ```
32 |
33 | 2. Verify the API is enabled:
34 | ```bash
35 | gcloud services list --filter=aiplatform.googleapis.com
36 | ```
37 |
38 | ### Permission Denied Errors
39 | **Problem**: "Permission denied" errors with Google Cloud APIs.
40 |
41 | **Solution**: Ensure your user or service account has the necessary IAM roles. For example, for Vertex AI, you often need `roles/aiplatform.user`. Grant roles using the `gcloud projects add-iam-policy-binding` command or the Cloud Console.
42 |
43 | ### Command Not Found: agent-starter-pack
44 |
45 | **Problem**: "Command not found" error after installation.
46 |
47 | **Solution**:
48 |
49 | 1. Verify installation:
50 | ```bash
51 | pip list | grep agent-starter-pack
52 | ```
53 | 2. Check PATH:
54 | ```bash
55 | echo $PATH
56 | ```
57 | 3. Reinstall if needed:
58 | ```bash
59 | pip install --user agent-starter-pack
60 | ```
61 | 4. For pipx:
62 | ```bash
63 | pipx ensurepath
64 | source ~/.bashrc # or ~/.zshrc
65 | ```
66 |
67 | ## Project Creation Issues
68 |
69 | ### Project Creation Fails
70 |
71 | **Problem**: `agent-starter-pack create` fails.
72 |
73 | **Solution**:
74 |
75 | 1. **Check Error Messages:** Examine output for clues.
76 | 2. **Write Permissions:** Ensure write access to the directory.
77 | 3. **Project Name:** Use lowercase letters, numbers and hyphens only.
78 | 4. **Debug Mode:** Consider using debug mode to get more detailed error information:
79 | ```bash
80 | agent-starter-pack create my-project-name --debug
81 | ```
82 |
83 | ### Issues with Agent Engine
84 |
85 | Consider leveraging the [public product documentation](https://cloud.google.com/vertex-ai/generative-ai/docs/agent-engine/troubleshooting/set-up)
86 |
87 | ## Getting More Help
88 |
89 | If issues persist:
90 |
91 | 1. **Check GitHub Issues:** Search for existing Github issues in the `agent-starter-pack` Github repository.
92 | 2. **File a New Issue:** Provide:
93 |
94 | * Problem description.
95 | * Steps to reproduce.
96 | * Error messages (preferably run with `--debug` flag for detailed logs).
97 | * Environment: OS, Python version, `agent-starter-pack` version, installation method, shell.
98 |
--------------------------------------------------------------------------------
/tests/test_frontend/test_utils/test_local_chat_history.py:
--------------------------------------------------------------------------------
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 | from pathlib import Path
16 |
17 | import pytest
18 | import yaml
19 |
20 | from frontend.utils.local_chat_history import LocalChatMessageHistory
21 |
22 |
23 | @pytest.fixture
24 | def chat_history(tmp_path: Path) -> LocalChatMessageHistory:
25 | """Create a temporary chat history instance"""
26 | return LocalChatMessageHistory(
27 | user_id="test_user", session_id="test_session", base_dir=str(tmp_path)
28 | )
29 |
30 |
31 | def test_init_creates_directory(tmp_path: Path) -> None:
32 | """Test directory creation on initialization"""
33 | user_dir = tmp_path / "test_user"
34 | assert not user_dir.exists()
35 |
36 | LocalChatMessageHistory(
37 | user_id="test_user", session_id="test_session", base_dir=str(tmp_path)
38 | )
39 |
40 | assert user_dir.exists()
41 |
42 |
43 | def test_get_session(chat_history: LocalChatMessageHistory) -> None:
44 | """Test session ID and file path update"""
45 | chat_history.get_session("new_session")
46 | assert chat_history.session_id == "new_session"
47 | assert chat_history.session_file.endswith("new_session.yaml")
48 |
49 |
50 | def test_upsert_session(chat_history: LocalChatMessageHistory) -> None:
51 | """Test session update/insert"""
52 | session = {
53 | "title": "Test Chat",
54 | "messages": [
55 | {"type": "human", "content": "Hello"},
56 | {"type": "ai", "content": "Hi there"},
57 | ],
58 | }
59 |
60 | chat_history.upsert_session(session)
61 |
62 | # Verify file was created
63 | assert Path(chat_history.session_file).exists()
64 |
65 | # Verify content
66 | with open(chat_history.session_file, encoding="utf-8") as f:
67 | saved_data = yaml.safe_load(f)
68 | assert len(saved_data) == 1
69 | assert saved_data[0]["title"] == "Test Chat"
70 | assert len(saved_data[0]["messages"]) == 2
71 |
72 |
73 | def test_get_all_conversations(chat_history: LocalChatMessageHistory) -> None:
74 | """Test retrieving all conversations"""
75 | # Create some test conversations
76 | sessions = {
77 | "session1": {"title": "Chat 1", "messages": []},
78 | "session2": {"title": "Chat 2", "messages": []},
79 | }
80 |
81 | for session_id, session in sessions.items():
82 | chat_history.get_session(session_id)
83 | chat_history.upsert_session(session)
84 |
85 | conversations = chat_history.get_all_conversations()
86 | assert len(conversations) == 2
87 | assert "session1" in conversations
88 | assert "session2" in conversations
89 |
--------------------------------------------------------------------------------
/tests/unit/README_MAKEFILE_TESTS.md:
--------------------------------------------------------------------------------
1 | # Makefile Template Test Suite
2 |
3 | Regression tests for `agent-starter-pack/base_template/Makefile` template refactoring. Ensures changes don't alter generated output across agent types, deployment targets, and feature combinations.
4 |
5 | ## Coverage
6 |
7 | Tests 9 configurations: ADK Base/Live (Cloud Run/Agent Engine), Agentic RAG (Vertex AI/Vector Search), LangGraph, Custom Commands, Agent Garden.
8 |
9 | ## Running Tests
10 |
11 | ```bash
12 | # All tests
13 | uv run pytest tests/unit/test_makefile_template.py -v
14 |
15 | # Specific categories (use -k filter)
16 | uv run pytest tests/unit/test_makefile_template.py -v -k "test_makefile_hash" # Fastest
17 | uv run pytest tests/unit/test_makefile_template.py -v -k "test_makefile_snapshot" # With diffs
18 | uv run pytest tests/unit/test_makefile_template.py -v -k "test_adk_live" # Specific feature
19 | ```
20 |
21 | ## Refactoring Workflow
22 |
23 | 1. Run tests before changes (verify baseline)
24 | 2. Make incremental changes to `agent-starter-pack/base_template/Makefile`
25 | 3. Run tests frequently to catch issues
26 | 4. Verify all tests pass after refactoring
27 |
28 | ## Test Failures
29 |
30 | **Snapshot failure**: Generated Makefile changed. Review diff with `git diff tests/fixtures/makefile_snapshots/.makefile`. If intentional, delete snapshot and rerun.
31 |
32 | **Hash failure**: Content changed. If intentional, delete `tests/fixtures/makefile_hashes.json` and rerun.
33 |
34 | **Feature failure**: Required target missing. Check Jinja2 conditionals in template.
35 |
36 | ## Updating Baselines
37 |
38 | ```bash
39 | # All baselines
40 | rm -rf tests/fixtures/makefile_snapshots/*.makefile tests/fixtures/makefile_hashes.json
41 | uv run pytest tests/unit/test_makefile_template.py -v
42 |
43 | # Specific config
44 | rm tests/fixtures/makefile_snapshots/.makefile
45 | uv run pytest tests/unit/test_makefile_template.py::TestMakefileGeneration::test_makefile_snapshot[] -v
46 | ```
47 |
48 | ## Test Types
49 |
50 | - **Snapshot**: Full output diffs (`tests/fixtures/makefile_snapshots/`) - for debugging
51 | - **Hash**: SHA256 comparison (`tests/fixtures/makefile_hashes.json`) - for CI/CD speed
52 | - **Feature**: Target presence validation - for functionality verification
53 |
54 | ## Adding Configurations
55 |
56 | 1. Add to `TEST_CONFIGURATIONS` in `test_makefile_template.py`
57 | 2. Run tests to generate baseline: `uv run pytest tests/unit/test_makefile_template.py -v`
58 | 3. Verify snapshot: `cat tests/fixtures/makefile_snapshots/.makefile`
59 |
60 | ## CI/CD
61 |
62 | ```yaml
63 | - name: Test Makefile Template
64 | run: uv run pytest tests/unit/test_makefile_template.py -v
65 | ```
66 |
67 | ## Refactoring Tips
68 |
69 | - Make small, incremental changes
70 | - Run tests frequently
71 | - Use Jinja2 variables for reusability
72 | - Document complex conditionals
73 | - Group related targets by agent/deployment type
74 |
75 | ## Troubleshooting
76 |
77 | - **Slow tests**: Use hash tests (`-k "test_makefile_hash"`)
78 | - **Need diffs**: Use snapshot tests (`-k "test_makefile_snapshot"`)
79 | - **Jinja2 errors**: Check error message for line number
80 | - **Missing variables**: `StrictUndefined` is already enabled
81 |
--------------------------------------------------------------------------------
/agent_starter_pack/deployment_targets/agent_engine/tests/load_test/README.md:
--------------------------------------------------------------------------------
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.utils.expose_app --mode remote --remote-id
20 | ```
21 |
22 | Or if you have `deployment_metadata.json` in your project root:
23 |
24 | ```bash
25 | uv run python -m 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
60 | make backend
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 |
85 |
--------------------------------------------------------------------------------
/tests/fixtures/makefile_snapshots/langgraph_cloud_run_no_data.makefile:
--------------------------------------------------------------------------------
1 | # ==============================================================================
2 | # Installation & Setup
3 | # ==============================================================================
4 |
5 | # Install dependencies using uv package manager
6 | install:
7 | @command -v uv >/dev/null 2>&1 || { echo "uv is not installed. Installing uv..."; curl -LsSf https://astral.sh/uv/0.8.13/install.sh | sh; source $HOME/.local/bin/env; }
8 | uv sync --dev --extra streamlit
9 |
10 | # ==============================================================================
11 | # Playground Targets
12 | # ==============================================================================
13 |
14 | # Launch local dev playground
15 | playground:
16 | @echo "==============================================================================="
17 | @echo "| 🚀 Starting your agent playground... |"
18 | @echo "| |"
19 | @echo "| 💡 Try asking: How can you help?|"
20 | @echo "==============================================================================="
21 | uv run uvicorn test_langgraph.server:app --host localhost --port 8000 --reload &
22 | uv run streamlit run frontend/streamlit_app.py --browser.serverAddress=localhost --server.enableCORS=false --server.enableXsrfProtection=false
23 |
24 | # ==============================================================================
25 | # Backend Deployment Targets
26 | # ==============================================================================
27 |
28 | # Deploy the agent remotely
29 | # Usage: make backend [IAP=true] [PORT=8080] - Set IAP=true to enable Identity-Aware Proxy, PORT to specify container port
30 | backend:
31 | PROJECT_ID=$$(gcloud config get-value project) && \
32 | gcloud beta run deploy test-langgraph \
33 | --source . \
34 | --memory "4Gi" \
35 | --project $$PROJECT_ID \
36 | --region "us-central1" \
37 | --no-allow-unauthenticated \
38 | --no-cpu-throttling \
39 | --labels "" \
40 | --set-env-vars \
41 | "COMMIT_SHA=$(shell git rev-parse HEAD)" \
42 | $(if $(IAP),--iap) \
43 | $(if $(PORT),--port=$(PORT))
44 |
45 |
46 | # ==============================================================================
47 | # Infrastructure Setup
48 | # ==============================================================================
49 |
50 | # Set up development environment resources using Terraform
51 | setup-dev-env:
52 | PROJECT_ID=$$(gcloud config get-value project) && \
53 | (cd deployment/terraform/dev && terraform init && terraform apply --var-file vars/env.tfvars --var dev_project_id=$$PROJECT_ID --auto-approve)
54 |
55 | # ==============================================================================
56 | # Testing & Code Quality
57 | # ==============================================================================
58 |
59 | # Run unit and integration tests
60 | test:
61 | uv run pytest tests/unit && uv run pytest tests/integration
62 |
63 | # Run code quality checks (codespell, ruff, mypy)
64 | lint:
65 | uv sync --dev --extra lint
66 | uv run codespell
67 | uv run ruff check . --diff
68 | uv run ruff format . --check --diff
69 | uv run mypy .
70 |
--------------------------------------------------------------------------------
/agent_starter_pack/base_template/deployment/terraform/log_sinks.tf:
--------------------------------------------------------------------------------
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 | resource "google_project_iam_member" "bigquery_data_editor" {
16 | for_each = local.deploy_project_ids
17 |
18 | project = each.value
19 | role = "roles/bigquery.dataEditor"
20 | member = module.log_export_to_bigquery[each.key].writer_identity
21 | }
22 |
23 | resource "google_bigquery_dataset" "feedback_dataset" {
24 | for_each = local.deploy_project_ids
25 | project = each.value
26 | dataset_id = replace("${var.project_name}_feedback", "-", "_")
27 | friendly_name = "${var.project_name}_feedback"
28 | location = var.region
29 | depends_on = [resource.google_project_service.cicd_services, resource.google_project_service.deploy_project_services]
30 | }
31 |
32 | resource "google_bigquery_dataset" "telemetry_logs_dataset" {
33 | for_each = local.deploy_project_ids
34 | project = each.value
35 | dataset_id = replace("${var.project_name}_telemetry", "-", "_")
36 | friendly_name = "${var.project_name}_telemetry"
37 | location = var.region
38 | depends_on = [resource.google_project_service.cicd_services, resource.google_project_service.deploy_project_services]
39 | }
40 |
41 | module "log_export_to_bigquery" {
42 | for_each = local.deploy_project_ids
43 |
44 | source = "terraform-google-modules/log-export/google"
45 | version = "10.0.0"
46 |
47 | log_sink_name = "${var.project_name}_telemetry"
48 | parent_resource_type = "project"
49 | parent_resource_id = each.value
50 | destination_uri = "bigquery.googleapis.com/projects/${each.value}/datasets/${google_bigquery_dataset.telemetry_logs_dataset[each.key].dataset_id}"
51 | filter = var.telemetry_logs_filter
52 | bigquery_options = { use_partitioned_tables = true }
53 | unique_writer_identity = true
54 | depends_on = [google_bigquery_dataset.telemetry_logs_dataset]
55 | }
56 |
57 | module "feedback_export_to_bigquery" {
58 | for_each = local.deploy_project_ids
59 |
60 | source = "terraform-google-modules/log-export/google"
61 | version = "10.0.0"
62 | log_sink_name = "${var.project_name}_feedback"
63 | parent_resource_type = "project"
64 | parent_resource_id = each.value
65 | destination_uri = "bigquery.googleapis.com/projects/${each.value}/datasets/${google_bigquery_dataset.feedback_dataset[each.key].dataset_id}"
66 | filter = var.feedback_logs_filter
67 | bigquery_options = { use_partitioned_tables = true }
68 | unique_writer_identity = true
69 | depends_on = [google_bigquery_dataset.feedback_dataset]
70 | }
71 |
--------------------------------------------------------------------------------
/agent_starter_pack/cli/utils/version.py:
--------------------------------------------------------------------------------
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 | """Version checking utilities for the CLI."""
16 |
17 | import logging
18 | from importlib.metadata import PackageNotFoundError, version
19 |
20 | import requests
21 | from packaging import version as pkg_version
22 | from rich.console import Console
23 |
24 | console = Console()
25 |
26 | PACKAGE_NAME = "agent-starter-pack"
27 |
28 |
29 | def get_current_version() -> str:
30 | """Get the current installed version of the package."""
31 | try:
32 | return version(PACKAGE_NAME)
33 | except PackageNotFoundError:
34 | # For development environments where package isn't installed
35 | return "0.0.0" # Default if version can't be determined
36 |
37 |
38 | def get_latest_version() -> str:
39 | """Get the latest version available on PyPI."""
40 | try:
41 | response = requests.get(f"https://pypi.org/pypi/{PACKAGE_NAME}/json", timeout=2)
42 | if response.status_code == 200:
43 | return response.json()["info"]["version"]
44 | return "0.0.0"
45 | except Exception:
46 | return "0.0.0" # Default if PyPI can't be reached
47 |
48 |
49 | def check_for_updates() -> tuple[bool, str, str]:
50 | """Check if a newer version of the package is available.
51 |
52 | Returns:
53 | Tuple of (needs_update, current_version, latest_version)
54 | """
55 | current = get_current_version()
56 | latest = get_latest_version()
57 |
58 | needs_update = pkg_version.parse(latest) > pkg_version.parse(current)
59 |
60 | return needs_update, current, latest
61 |
62 |
63 | def display_update_message() -> None:
64 | """Check for updates and display a message if an update is available."""
65 | try:
66 | needs_update, current, latest = check_for_updates()
67 |
68 | if needs_update:
69 | console.print(
70 | f"\n[yellow]⚠️ Update available: {current} → {latest}[/]",
71 | highlight=False,
72 | )
73 | console.print(
74 | f"[yellow]Run `pip install --upgrade {PACKAGE_NAME}` to update.",
75 | highlight=False,
76 | )
77 | console.print(
78 | f"[yellow]Or, if you used pipx: `pipx upgrade {PACKAGE_NAME}`",
79 | highlight=False,
80 | )
81 | console.print(
82 | f"[yellow]Or, if you used uv: `uv pip install --upgrade {PACKAGE_NAME}`",
83 | highlight=False,
84 | )
85 | except Exception as e:
86 | # Don't let version checking errors affect the CLI
87 | logging.debug(f"Error checking for updates: {e}")
88 |
--------------------------------------------------------------------------------
/tests/fixtures/makefile_snapshots/adk_base_cloud_run_no_data.makefile:
--------------------------------------------------------------------------------
1 | # ==============================================================================
2 | # Installation & Setup
3 | # ==============================================================================
4 |
5 | # Install dependencies using uv package manager
6 | install:
7 | @command -v uv >/dev/null 2>&1 || { echo "uv is not installed. Installing uv..."; curl -LsSf https://astral.sh/uv/0.8.13/install.sh | sh; source $HOME/.local/bin/env; }
8 | uv sync --dev
9 |
10 | # ==============================================================================
11 | # Playground Targets
12 | # ==============================================================================
13 |
14 | # Launch local dev playground
15 | playground:
16 | @echo "==============================================================================="
17 | @echo "| 🚀 Starting your agent playground... |"
18 | @echo "| |"
19 | @echo "| 💡 Try asking: What can you help me with?|"
20 | @echo "| |"
21 | @echo "| 🔍 IMPORTANT: Select the 'test_adk_base' folder to interact with your agent. |"
22 | @echo "==============================================================================="
23 | uv run adk web . --port 8501 --reload_agents
24 |
25 | # ==============================================================================
26 | # Backend Deployment Targets
27 | # ==============================================================================
28 |
29 | # Deploy the agent remotely
30 | # Usage: make backend [IAP=true] [PORT=8080] - Set IAP=true to enable Identity-Aware Proxy, PORT to specify container port
31 | backend:
32 | PROJECT_ID=$$(gcloud config get-value project) && \
33 | gcloud beta run deploy test-adk-base \
34 | --source . \
35 | --memory "4Gi" \
36 | --project $$PROJECT_ID \
37 | --region "us-central1" \
38 | --no-allow-unauthenticated \
39 | --no-cpu-throttling \
40 | --labels "created-by=adk" \
41 | --set-env-vars \
42 | "COMMIT_SHA=$(shell git rev-parse HEAD)" \
43 | $(if $(IAP),--iap) \
44 | $(if $(PORT),--port=$(PORT))
45 |
46 |
47 | # ==============================================================================
48 | # Infrastructure Setup
49 | # ==============================================================================
50 |
51 | # Set up development environment resources using Terraform
52 | setup-dev-env:
53 | PROJECT_ID=$$(gcloud config get-value project) && \
54 | (cd deployment/terraform/dev && terraform init && terraform apply --var-file vars/env.tfvars --var dev_project_id=$$PROJECT_ID --auto-approve)
55 |
56 | # ==============================================================================
57 | # Testing & Code Quality
58 | # ==============================================================================
59 |
60 | # Run unit and integration tests
61 | test:
62 | uv run pytest tests/unit && uv run pytest tests/integration
63 |
64 | # Run code quality checks (codespell, ruff, mypy)
65 | lint:
66 | uv sync --dev --extra lint
67 | uv run codespell
68 | uv run ruff check . --diff
69 | uv run ruff format . --check --diff
70 | uv run mypy .
71 |
--------------------------------------------------------------------------------
/tests/cli/utils/test_cicd.py:
--------------------------------------------------------------------------------
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 | """Tests for CI/CD utility functions."""
16 |
17 | from unittest.mock import MagicMock, patch
18 |
19 | import pytest
20 | from cli.utils.cicd import ProjectConfig, print_cicd_summary, run_command
21 |
22 |
23 | @pytest.fixture
24 | def mock_console() -> MagicMock:
25 | """Mock console for testing output"""
26 | with patch("cli.utils.cicd.console") as mock:
27 | yield mock
28 |
29 |
30 | @pytest.fixture
31 | def mock_run_command() -> MagicMock:
32 | """Mock run_command function"""
33 | with patch("agent_starter_pack.cli.utils.cicd.run_command") as mock:
34 | yield mock
35 |
36 |
37 | def test_project_config() -> None:
38 | """Test ProjectConfig initialization with minimal required fields"""
39 | config = ProjectConfig(
40 | staging_project_id="test-staging",
41 | prod_project_id="test-prod",
42 | cicd_project_id="test-cicd",
43 | agent="test-agent",
44 | deployment_target="cloud-run",
45 | repository_name="test-repo",
46 | repository_owner="test-owner",
47 | dev_project_id="test-dev",
48 | )
49 |
50 | assert config.dev_project_id == "test-dev"
51 | assert config.region == "us-central1" # default value
52 | assert config.git_provider == "github" # default value
53 |
54 |
55 | def test_print_cicd_summary(mock_console: MagicMock) -> None:
56 | """Test CICD summary printing"""
57 | config = ProjectConfig(
58 | staging_project_id="test-staging",
59 | prod_project_id="test-prod",
60 | cicd_project_id="test-cicd",
61 | agent="test-agent",
62 | deployment_target="cloud-run",
63 | repository_name="test-repo",
64 | repository_owner="test-owner",
65 | dev_project_id="test-dev",
66 | )
67 |
68 | print_cicd_summary(
69 | config=config,
70 | github_username="test-user",
71 | repo_url="https://github.com/test-user/test-repo",
72 | cloud_build_url="https://console.cloud.google.com/cloud-build/builds?project=test-cicd",
73 | )
74 |
75 | # Verify specific expected messages were printed
76 | assert mock_console.print.call_count > 0
77 |
78 |
79 | def test_run_command(capsys: pytest.CaptureFixture) -> None:
80 | """Test run_command output formatting"""
81 | with patch("subprocess.run") as mock_run:
82 | mock_run.return_value = MagicMock(returncode=0, stdout="test output", stderr="")
83 |
84 | result = run_command(["test", "command"], capture_output=True)
85 |
86 | captured = capsys.readouterr()
87 | assert "🔄 Running command: test command" in captured.out
88 | assert result.stdout == "test output"
89 |
--------------------------------------------------------------------------------
/docs/guide/getting-started.md:
--------------------------------------------------------------------------------
1 | # 🚀 Getting Started
2 |
3 | This guide quickly walks you through setting up your first agent project.
4 |
5 | **Want zero setup?** 👉 [Try in Firebase Studio](https://studio.firebase.google.com/new?template=https%3A%2F%2Fgithub.com%2FGoogleCloudPlatform%2Fagent-starter-pack%2Ftree%2Fmain%2Fsrc%2Fresources%2Fidx) or in [Cloud Shell](https://shell.cloud.google.com/cloudshell/editor?cloudshell_git_repo=https%3A%2F%2Fgithub.com%2Feliasecchig%2Fasp-open-in-cloud-shell&cloudshell_print=open-in-cs)
6 |
7 | ### Prerequisites
8 |
9 | **Python 3.10+** | **Google Cloud SDK** [Install Guide](https://cloud.google.com/sdk/docs/install) | **Terraform** [Install Guide](https://developer.hashicorp.com/terraform/downloads) | **`uv` (Optional, Recommended)** [Install Guide](https://docs.astral.sh/uv/getting-started/installation/)
10 |
11 | ### 1. Create Your Agent Project
12 |
13 | You can use the `pip` workflow for a traditional setup, or `uvx` to create a project in a single command without a permanent install. Choose your preferred method below.
14 |
15 | ::: code-group
16 |
17 | ```bash [pip]
18 | # 1. Create and activate a virtual environment
19 | python -m venv .venv
20 | source .venv/bin/activate
21 |
22 | # 2. Install the package
23 | pip install agent-starter-pack
24 |
25 | # 3. Run the create command
26 | agent-starter-pack create my-awesome-agent
27 | ```
28 |
29 | ```bash [⚡ uvx]
30 | # This single command downloads and runs the latest version
31 | uvx agent-starter-pack create my-awesome-agent
32 | ```
33 |
34 | :::
35 |
36 | No matter which method you choose, the `create` command will:
37 | * Let you choose an agent template (e.g., `adk_base`, `agentic_rag`).
38 | * Let you select a deployment target (e.g., `cloud_run`, `agent_engine`).
39 | * Generate a complete project structure (backend, optional frontend, deployment infra).
40 |
41 | **Examples:**
42 |
43 | ```bash
44 | # You can also pass flags to skip the prompts
45 | agent-starter-pack create my-adk-agent -a adk_base -d agent_engine
46 | ```
47 |
48 | ### 2. Explore and Run Locally
49 |
50 | Now, navigate into your new project and run its setup commands.
51 |
52 | ```bash
53 | cd my-awesome-agent && make install && make playground
54 | ```
55 |
56 | Inside your new project directory (`my-awesome-agent`), you'll find:
57 |
58 | * `app/`: Backend agent code (or custom directory name if configured).
59 | * `deployment/`: Terraform infrastructure code.
60 | * `tests/`: Unit and integration tests for your agent.
61 | * `notebooks/`: Jupyter notebooks for getting started with evaluation.
62 | * `frontend/`: (If applicable) Web UI for interacting with your agent.
63 | * `README.md`: **Project-specific instructions for running locally and deploying.**
64 |
65 | ➡️ **Follow the instructions in *your new project's* `README.md` to run it locally.**
66 |
67 | ### Next Steps
68 |
69 | You're ready to go! See the [Development Guide](/guide/development-guide) for detailed instructions on extending, customizing and deploying your agent.
70 |
71 | - **Add Data (RAG):** Configure [Data Ingestion](/guide/data-ingestion) for knowledge-based agents.
72 | - **Monitor Performance:** Explore [Observability](/guide/observability) features for production monitoring.
73 | - **Deploy to Production:** Follow the [Deployment Guide](/guide/deployment) to deploy your agent to Google Cloud.
--------------------------------------------------------------------------------
/docs/guide/data-ingestion.md:
--------------------------------------------------------------------------------
1 | # Data Ingestion Pipeline for RAG
2 |
3 | The Agent Starter Pack simplifies incorporating data ingestion into your agent projects. This is especially useful for agents requiring document processing and retrieval, such as Retrieval Augmented Generation (RAG) applications.
4 |
5 | ## Overview
6 |
7 | Data ingestion automates:
8 |
9 | - Loading data from various sources.
10 | - Processing and chunking documents.
11 | - Generating embeddings with Vertex AI.
12 | - Storing processed data and embeddings in **Vertex AI Search** or **Vertex AI Vector Search**.
13 | - Scheduling periodic data updates.
14 |
15 | ## When to Include Data Ingestion
16 |
17 | Consider data ingestion if:
18 |
19 | - Your agent needs to search or reference extensive documentation.
20 | - You're developing a RAG-based application.
21 | - Your agent's knowledge base requires periodic updates.
22 | - You want to keep your agent's content fresh and searchable.
23 |
24 | ## Usage
25 |
26 | ### Project Creation
27 |
28 | Include data ingestion during project creation in two ways:
29 |
30 | 1. **Automatic Inclusion**: Some agents (e.g., those designed for RAG like `agentic_rag`) automatically include it due to their nature. You will be prompted to select a datastore (`vertex_ai_search` or `vertex_ai_vector_search`) if not specified.
31 |
32 | 2. **Optional Inclusion**: For other agents, add it using the `--include-data-ingestion` flag and specify the desired datastore with `--datastore` (or `-ds`):
33 |
34 | ```bash
35 | # Using Vertex AI Search
36 | agent-starter-pack create my-agent-project --include-data-ingestion -ds vertex_ai_search
37 |
38 | # Using Vertex AI Vector Search
39 | agent-starter-pack create my-agent-project --include-data-ingestion -ds vertex_ai_vector_search
40 | ```
41 | If `--datastore` is omitted when `--include-data-ingestion` is used, you will be prompted to choose one.
42 |
43 | ### Infrastructure Setup
44 |
45 | The Terraform IaC configures the necessary infrastructure based on your chosen datastore:
46 |
47 | - **Vertex AI Search**: Datastores.
48 | - **Vertex AI Vector Search**: Indexes, Index Endpoints, and Buckets for staging data.
49 | - Necessary service accounts and permissions.
50 | - Storage buckets for pipeline artifacts.
51 | - BigQuery datasets (if applicable).
52 |
53 | ## Getting Started
54 |
55 | 1. Create your project with data ingestion, specifying your datastore:
56 |
57 | ```bash
58 | # Example with Vertex AI Search
59 | agent-starter-pack create my-project -ds vertex_ai_search
60 |
61 | # Example with Vertex AI Vector Search
62 | agent-starter-pack create my-project -ds vertex_ai_vector_search
63 | ```
64 |
65 | 2. Follow the setup instructions in the generated `data_ingestion/README.md`. Deploy the Terraform infrastructure (at least in your development project) before running the data pipeline.
66 |
67 | ## Learn More
68 |
69 | - [Vertex AI Pipelines](https://cloud.google.com/vertex-ai/docs/pipelines/introduction) for pipeline management.
70 | - [Vertex AI Search documentation](https://cloud.google.com/generative-ai-app-builder/docs/enterprise-search-introduction) for search capabilities.
71 | - [Vertex AI Vector Search documentation](https://cloud.google.com/vertex-ai/docs/vector-search/overview) for vector database capabilities.
72 |
--------------------------------------------------------------------------------
/tests/fixtures/makefile_snapshots/agent_with_agent_garden.makefile:
--------------------------------------------------------------------------------
1 | # ==============================================================================
2 | # Installation & Setup
3 | # ==============================================================================
4 |
5 | # Install dependencies using uv package manager
6 | install:
7 | @command -v uv >/dev/null 2>&1 || { echo "uv is not installed. Installing uv..."; curl -LsSf https://astral.sh/uv/0.8.13/install.sh | sh; source $HOME/.local/bin/env; }
8 | uv sync --dev
9 |
10 | # ==============================================================================
11 | # Playground Targets
12 | # ==============================================================================
13 |
14 | # Launch local dev playground
15 | playground:
16 | @echo "==============================================================================="
17 | @echo "| 🚀 Starting your agent playground... |"
18 | @echo "| |"
19 | @echo "| 💡 Try asking: Agent garden question|"
20 | @echo "| |"
21 | @echo "| 🔍 IMPORTANT: Select the 'test_garden' folder to interact with your agent. |"
22 | @echo "==============================================================================="
23 | uv run adk web . --port 8501 --reload_agents
24 |
25 | # ==============================================================================
26 | # Backend Deployment Targets
27 | # ==============================================================================
28 |
29 | # Deploy the agent remotely
30 | # Usage: make backend [IAP=true] [PORT=8080] - Set IAP=true to enable Identity-Aware Proxy, PORT to specify container port
31 | backend:
32 | PROJECT_ID=$$(gcloud config get-value project) && \
33 | gcloud beta run deploy test-garden \
34 | --source . \
35 | --memory "4Gi" \
36 | --project $$PROJECT_ID \
37 | --region "us-central1" \
38 | --no-allow-unauthenticated \
39 | --no-cpu-throttling \
40 | --labels "created-by=adk,deployed-with=agent-garden,vertex-agent-sample-id=sample-123,vertex-agent-sample-publisher=google" \
41 | --set-env-vars \
42 | "COMMIT_SHA=$(shell git rev-parse HEAD)" \
43 | $(if $(IAP),--iap) \
44 | $(if $(PORT),--port=$(PORT))
45 |
46 |
47 | # ==============================================================================
48 | # Infrastructure Setup
49 | # ==============================================================================
50 |
51 | # Set up development environment resources using Terraform
52 | setup-dev-env:
53 | PROJECT_ID=$$(gcloud config get-value project) && \
54 | (cd deployment/terraform/dev && terraform init && terraform apply --var-file vars/env.tfvars --var dev_project_id=$$PROJECT_ID --auto-approve)
55 |
56 | # ==============================================================================
57 | # Testing & Code Quality
58 | # ==============================================================================
59 |
60 | # Run unit and integration tests
61 | test:
62 | uv run pytest tests/unit && uv run pytest tests/integration
63 |
64 | # Run code quality checks (codespell, ruff, mypy)
65 | lint:
66 | uv sync --dev --extra lint
67 | uv run codespell
68 | uv run ruff check . --diff
69 | uv run ruff format . --check --diff
70 | uv run mypy .
71 |
--------------------------------------------------------------------------------