agent-starter-pack 0.17.4__py3-none-any.whl → 0.18.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

@@ -127,6 +127,8 @@ playground-remote: build-frontend-if-needed
127
127
  @echo "==============================================================================="
128
128
  uv run python -m {{cookiecutter.agent_directory}}.utils.expose_app --mode remote
129
129
  {%- endif %}
130
+ {%- endif %}
131
+ {%- if cookiecutter.is_adk_live and cookiecutter.deployment_target == 'agent_engine' %}
130
132
 
131
133
  # Start the frontend UI separately for development (requires backend running separately)
132
134
  ui:
@@ -226,3 +228,20 @@ lint:
226
228
  uv run ruff check . --diff
227
229
  uv run ruff format . --check --diff
228
230
  uv run mypy .
231
+ {%- if cookiecutter.is_adk and cookiecutter.deployment_target == 'agent_engine' %}
232
+
233
+ # ==============================================================================
234
+ # Gemini Enterprise Integration
235
+ # ==============================================================================
236
+
237
+ # Register the deployed agent to Gemini Enterprise
238
+ # Usage: make register-gemini-enterprise GEMINI_ENTERPRISE_APP_ID=projects/{project_number}/locations/{location}/collections/{collection}/engines/{engine_id} [AGENT_ENGINE_ID=<id>] # Defaults to deployment_metadata.json
239
+ register-gemini-enterprise:
240
+ uvx --from agent-starter-pack agent-starter-pack-register-gemini-enterprise \
241
+ $(if $(GEMINI_ENTERPRISE_APP_ID),--gemini-enterprise-app-id="$(GEMINI_ENTERPRISE_APP_ID)",) \
242
+ $(if $(AGENT_ENGINE_ID),--agent-engine-id="$(AGENT_ENGINE_ID)",) \
243
+ $(if $(GEMINI_DISPLAY_NAME),--display-name="$(GEMINI_DISPLAY_NAME)",) \
244
+ $(if $(GEMINI_DESCRIPTION),--description="$(GEMINI_DESCRIPTION)",) \
245
+ $(if $(GEMINI_TOOL_DESCRIPTION),--tool-description="$(GEMINI_TOOL_DESCRIPTION)",) \
246
+ $(if $(GEMINI_AUTHORIZATION_ID),--authorization-id="$(GEMINI_AUTHORIZATION_ID)",)
247
+ {%- endif %}
@@ -59,16 +59,21 @@ make install && make playground
59
59
  {%- endif %}
60
60
  {%- if cookiecutter.deployment_target == 'cloud_run' %}
61
61
  | `make playground` | Launch local development environment with backend and frontend{%- if cookiecutter.is_adk %} - leveraging `adk web` command. {%- endif %}|
62
- | `make backend` | Deploy agent to Cloud Run (use `IAP=true` to enable Identity-Aware Proxy) |
63
- | `make local-backend` | Launch local development server |
64
- {%- if cookiecutter.deployment_target == 'cloud_run' %}
65
- {%- if cookiecutter.is_adk_live %}
66
- | `make ui` | Launch Agent Playground front-end only |
67
- {%- endif %}
68
- {%- endif %}
62
+ | `make backend` | Deploy agent to Cloud Run (use `IAP=true` to enable Identity-Aware Proxy, `PORT=8080` to specify container port) |
63
+ | `make local-backend` | Launch local development server with hot-reload |
69
64
  {%- elif cookiecutter.deployment_target == 'agent_engine' %}
70
65
  | `make playground` | Launch Streamlit interface for testing agent locally and remotely |
71
66
  | `make backend` | Deploy agent to Agent Engine |
67
+ {%- if cookiecutter.is_adk_live %}
68
+ | `make local-backend` | Launch local development server with hot-reload |
69
+ | `make ui` | Start the frontend UI separately for development (requires backend running separately) |
70
+ | `make playground-dev` | Launch dev playground with both frontend and backend hot-reload |
71
+ | `make playground-remote` | Connect to remote deployed agent with local frontend |
72
+ | `make build-frontend` | Build the frontend for production |
73
+ {%- endif %}
74
+ {%- if cookiecutter.is_adk %}
75
+ | `make register-gemini-enterprise` | Register deployed agent to Gemini Enterprise (see Makefile for parameters) |
76
+ {%- endif %}
72
77
  {%- endif %}
73
78
  | `make test` | Run unit and integration tests |
74
79
  | `make lint` | Run code quality checks (codespell, ruff, mypy) |
@@ -76,7 +81,6 @@ make install && make playground
76
81
  {%- if cookiecutter.data_ingestion %}
77
82
  | `make data-ingestion`| Run data ingestion pipeline in the Dev environment |
78
83
  {%- endif %}
79
- | `uv run jupyter lab` | Launch Jupyter notebook |
80
84
 
81
85
  For full command options and usage, refer to the [Makefile](Makefile).
82
86
 
@@ -0,0 +1,406 @@
1
+ #!/usr/bin/env python3
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
+ """Utility to register an Agent Engine to Gemini Enterprise."""
17
+
18
+ import argparse
19
+ import json
20
+ import os
21
+ import sys
22
+ from pathlib import Path
23
+
24
+ import requests
25
+ import vertexai
26
+ from google.auth import default
27
+ from google.auth.transport.requests import Request as GoogleAuthRequest
28
+
29
+
30
+ def get_agent_engine_id(
31
+ agent_engine_id: str | None, metadata_file: str = "deployment_metadata.json"
32
+ ) -> str:
33
+ """Get the agent engine ID from parameter or deployment metadata.
34
+
35
+ Args:
36
+ agent_engine_id: Optional agent engine resource name
37
+ metadata_file: Path to deployment metadata JSON file
38
+
39
+ Returns:
40
+ The agent engine resource name
41
+
42
+ Raises:
43
+ ValueError: If agent_engine_id is not provided and metadata file doesn't exist
44
+ """
45
+ if agent_engine_id:
46
+ return agent_engine_id
47
+
48
+ # Try to read from deployment_metadata.json
49
+ metadata_path = Path(metadata_file)
50
+ if not metadata_path.exists():
51
+ raise ValueError(
52
+ f"No agent engine ID provided and {metadata_file} not found. "
53
+ "Please provide --agent-engine-id or deploy your agent first."
54
+ )
55
+
56
+ with open(metadata_path) as f:
57
+ metadata = json.load(f)
58
+ return metadata["remote_agent_engine_id"]
59
+
60
+
61
+ def get_access_token() -> str:
62
+ """Get Google Cloud access token.
63
+
64
+ Returns:
65
+ Access token string
66
+
67
+ Raises:
68
+ SystemExit: If authentication fails
69
+ """
70
+ try:
71
+ credentials, _ = default()
72
+ auth_req = GoogleAuthRequest()
73
+ credentials.refresh(auth_req)
74
+ return credentials.token
75
+ except Exception as e:
76
+ print(f"Error getting access token: {e}", file=sys.stderr)
77
+ print(
78
+ "Please ensure you are authenticated with 'gcloud auth application-default login'",
79
+ file=sys.stderr,
80
+ )
81
+ raise RuntimeError("Failed to get access token") from e
82
+
83
+
84
+ def get_agent_engine_metadata(agent_engine_id: str) -> tuple[str | None, str | None]:
85
+ """Fetch display_name and description from deployed Agent Engine.
86
+
87
+ Args:
88
+ agent_engine_id: Agent Engine resource name
89
+
90
+ Returns:
91
+ Tuple of (display_name, description) - either can be None if not found
92
+ """
93
+ parts = agent_engine_id.split("/")
94
+ if len(parts) < 6:
95
+ return None, None
96
+
97
+ project_id = parts[1]
98
+ location = parts[3]
99
+
100
+ try:
101
+ client = vertexai.Client(project=project_id, location=location)
102
+ agent_engine = client.agent_engines.get(name=agent_engine_id)
103
+
104
+ display_name = getattr(agent_engine.api_resource, "display_name", None)
105
+ description = getattr(agent_engine.api_resource, "description", None)
106
+
107
+ return display_name, description
108
+ except Exception as e:
109
+ print(
110
+ f"Warning: Could not fetch metadata from Agent Engine: {e}", file=sys.stderr
111
+ )
112
+ return None, None
113
+
114
+
115
+ def register_agent(
116
+ agent_engine_id: str,
117
+ gemini_enterprise_app_id: str,
118
+ display_name: str,
119
+ description: str,
120
+ tool_description: str,
121
+ project_id: str | None = None,
122
+ authorization_id: str | None = None,
123
+ ) -> dict:
124
+ """Register an agent engine to Gemini Enterprise.
125
+
126
+ This function attempts to create a new agent registration. If the agent is already
127
+ registered (same reasoning engine), it will automatically update the existing
128
+ registration instead.
129
+
130
+ Args:
131
+ agent_engine_id: Agent engine resource name (e.g., projects/.../reasoningEngines/...)
132
+ gemini_enterprise_app_id: Full Gemini Enterprise app resource name
133
+ (e.g., projects/{project_number}/locations/{location}/collections/{collection}/engines/{engine_id})
134
+ display_name: Display name for the agent in Gemini Enterprise
135
+ description: Description of the agent
136
+ tool_description: Description of what the tool does
137
+ project_id: Optional GCP project ID for billing (extracted from agent_engine_id if not provided)
138
+ authorization_id: Optional OAuth authorization ID
139
+ (e.g., projects/{project_number}/locations/global/authorizations/{auth_id})
140
+
141
+ Returns:
142
+ API response as dictionary
143
+
144
+ Raises:
145
+ requests.HTTPError: If the API request fails
146
+ ValueError: If gemini_enterprise_app_id format is invalid
147
+ """
148
+ # Parse Gemini Enterprise app resource name
149
+ # Format: projects/{project_number}/locations/{location}/collections/{collection}/engines/{engine_id}
150
+ parts = gemini_enterprise_app_id.split("/")
151
+ if (
152
+ len(parts) != 8
153
+ or parts[0] != "projects"
154
+ or parts[2] != "locations"
155
+ or parts[4] != "collections"
156
+ or parts[6] != "engines"
157
+ ):
158
+ raise ValueError(
159
+ f"Invalid GEMINI_ENTERPRISE_APP_ID format. Expected: "
160
+ f"projects/{{project_number}}/locations/{{location}}/collections/{{collection}}/engines/{{engine_id}}, "
161
+ f"got: {gemini_enterprise_app_id}"
162
+ )
163
+
164
+ project_number = parts[1]
165
+ as_location = parts[3]
166
+ collection = parts[5]
167
+ engine_id = parts[7]
168
+
169
+ # Use project from agent engine if not explicitly provided (for billing header)
170
+ if not project_id:
171
+ # Extract from agent_engine_id: projects/{project}/locations/{location}/reasoningEngines/{id}
172
+ agent_parts = agent_engine_id.split("/")
173
+ if len(agent_parts) > 1 and agent_parts[0] == "projects":
174
+ project_id = agent_parts[1]
175
+ else:
176
+ # Fallback to the project number from the Gemini Enterprise App ID.
177
+ project_id = project_number
178
+
179
+ # Get access token
180
+ access_token = get_access_token()
181
+
182
+ # Build API endpoint
183
+ url = (
184
+ f"https://discoveryengine.googleapis.com/v1alpha/projects/{project_number}/"
185
+ f"locations/{as_location}/collections/{collection}/engines/{engine_id}/"
186
+ "assistants/default_assistant/agents"
187
+ )
188
+
189
+ # Request headers
190
+ headers = {
191
+ "Authorization": f"Bearer {access_token}",
192
+ "Content-Type": "application/json",
193
+ "x-goog-user-project": project_id,
194
+ }
195
+
196
+ # Request body
197
+ adk_agent_definition: dict = {
198
+ "tool_settings": {"tool_description": tool_description},
199
+ "provisioned_reasoning_engine": {"reasoningEngine": agent_engine_id},
200
+ }
201
+
202
+ # Add OAuth authorization if provided
203
+ if authorization_id:
204
+ adk_agent_definition["authorizations"] = [authorization_id]
205
+
206
+ payload = {
207
+ "displayName": display_name,
208
+ "description": description,
209
+ "icon": {
210
+ "uri": "https://fonts.gstatic.com/s/i/short-term/release/googlesymbols/smart_toy/default/24px.svg"
211
+ },
212
+ "adk_agent_definition": adk_agent_definition,
213
+ }
214
+
215
+ print("Registering agent to Gemini Enterprise...")
216
+ print(f" Agent Engine: {agent_engine_id}")
217
+ print(f" Gemini Enterprise App: {gemini_enterprise_app_id}")
218
+ print(f" Display Name: {display_name}")
219
+ print(f" API Endpoint: {url}")
220
+
221
+ try:
222
+ # Try to create a new registration first
223
+ response = requests.post(url, headers=headers, json=payload, timeout=30)
224
+ response.raise_for_status()
225
+
226
+ result = response.json()
227
+ print("\n✅ Successfully registered agent to Gemini Enterprise!")
228
+ print(f" Agent Name: {result.get('name', 'N/A')}")
229
+ return result
230
+
231
+ except requests.exceptions.HTTPError as http_err:
232
+ # Check if the error is because the agent already exists
233
+ if response.status_code in (400, 409):
234
+ try:
235
+ error_data = response.json()
236
+ error_message = error_data.get("error", {}).get("message", "")
237
+
238
+ # Check if error indicates the agent already exists
239
+ if (
240
+ "already exists" in error_message.lower()
241
+ or "duplicate" in error_message.lower()
242
+ ):
243
+ print(
244
+ "\n⚠️ Agent already registered. Updating existing registration..."
245
+ )
246
+
247
+ # For update, we need to use the specific agent resource name
248
+ # The agent name should be in the error or we can construct it
249
+ # Format: {url}/{agent_id} but we need to find existing agent first
250
+
251
+ # List existing agents to find the one for this reasoning engine
252
+ list_response = requests.get(url, headers=headers, timeout=30)
253
+ list_response.raise_for_status()
254
+ agents_list = list_response.json().get("agents", [])
255
+
256
+ # Find the agent that matches our reasoning engine
257
+ existing_agent = None
258
+ for agent in agents_list:
259
+ re_name = (
260
+ agent.get("adk_agent_definition", {})
261
+ .get("provisioned_reasoning_engine", {})
262
+ .get("reasoningEngine", "")
263
+ )
264
+ if re_name == agent_engine_id:
265
+ existing_agent = agent
266
+ break
267
+
268
+ if existing_agent:
269
+ agent_name = existing_agent.get("name")
270
+ update_url = f"https://discoveryengine.googleapis.com/v1alpha/{agent_name}"
271
+
272
+ print(f" Updating agent: {agent_name}")
273
+
274
+ # PATCH request to update
275
+ update_response = requests.patch(
276
+ update_url, headers=headers, json=payload, timeout=30
277
+ )
278
+ update_response.raise_for_status()
279
+
280
+ result = update_response.json()
281
+ print(
282
+ "\n✅ Successfully updated agent registration in Gemini Enterprise!"
283
+ )
284
+ print(f" Agent Name: {result.get('name', 'N/A')}")
285
+ return result
286
+ else:
287
+ print(
288
+ "\n❌ Could not find existing agent to update",
289
+ file=sys.stderr,
290
+ )
291
+ raise
292
+ except (ValueError, KeyError):
293
+ # Failed to parse error response, raise original error
294
+ pass
295
+
296
+ # If not an "already exists" error, or update failed, raise the original error
297
+ print(f"\n❌ HTTP error occurred: {http_err}", file=sys.stderr)
298
+ print(f" Response: {response.text}", file=sys.stderr)
299
+ raise
300
+ except requests.exceptions.RequestException as req_err:
301
+ print(f"\n❌ Request error occurred: {req_err}", file=sys.stderr)
302
+ raise
303
+
304
+
305
+ def main() -> None:
306
+ """Main entry point for CLI."""
307
+ parser = argparse.ArgumentParser(
308
+ description="Register an Agent Engine to Gemini Enterprise"
309
+ )
310
+ parser.add_argument(
311
+ "--agent-engine-id",
312
+ help="Agent Engine resource name (e.g., projects/.../reasoningEngines/...). "
313
+ "If not provided, reads from deployment_metadata.json",
314
+ )
315
+ parser.add_argument(
316
+ "--metadata-file",
317
+ default="deployment_metadata.json",
318
+ help="Path to deployment metadata file (default: deployment_metadata.json)",
319
+ )
320
+ parser.add_argument(
321
+ "--gemini-enterprise-app-id",
322
+ help="Gemini Enterprise app full resource name "
323
+ "(e.g., projects/{project_number}/locations/{location}/collections/{collection}/engines/{engine_id}). "
324
+ "Can also be set via GEMINI_ENTERPRISE_APP_ID env var",
325
+ )
326
+ parser.add_argument(
327
+ "--display-name",
328
+ help="Display name for the agent. Can also be set via GEMINI_DISPLAY_NAME env var",
329
+ )
330
+ parser.add_argument(
331
+ "--description",
332
+ help="Description of the agent. Can also be set via GEMINI_DESCRIPTION env var",
333
+ )
334
+ parser.add_argument(
335
+ "--tool-description",
336
+ help="Description of what the tool does. Can also be set via GEMINI_TOOL_DESCRIPTION env var",
337
+ )
338
+ parser.add_argument(
339
+ "--project-id",
340
+ help="GCP project ID (extracted from agent-engine-id if not provided). "
341
+ "Can also be set via GOOGLE_CLOUD_PROJECT env var",
342
+ )
343
+ parser.add_argument(
344
+ "--authorization-id",
345
+ help="OAuth authorization resource name "
346
+ "(e.g., projects/{project_number}/locations/global/authorizations/{auth_id}). "
347
+ "Can also be set via GEMINI_AUTHORIZATION_ID env var",
348
+ )
349
+
350
+ args = parser.parse_args()
351
+
352
+ # Get agent engine ID
353
+ try:
354
+ agent_engine_id = get_agent_engine_id(args.agent_engine_id, args.metadata_file)
355
+ except ValueError as e:
356
+ print(f"Error: {e}", file=sys.stderr)
357
+ sys.exit(1)
358
+
359
+ # Auto-detect display_name and description from Agent Engine
360
+ auto_display_name, auto_description = get_agent_engine_metadata(agent_engine_id)
361
+
362
+ gemini_enterprise_app_id = args.gemini_enterprise_app_id or os.getenv(
363
+ "GEMINI_ENTERPRISE_APP_ID"
364
+ )
365
+ if not gemini_enterprise_app_id:
366
+ print(
367
+ "Error: --gemini-enterprise-app-id or GEMINI_ENTERPRISE_APP_ID env var required",
368
+ file=sys.stderr,
369
+ )
370
+ sys.exit(1)
371
+
372
+ display_name = (
373
+ args.display_name
374
+ or os.getenv("GEMINI_DISPLAY_NAME")
375
+ or auto_display_name
376
+ or "My Agent"
377
+ )
378
+ description = (
379
+ args.description
380
+ or os.getenv("GEMINI_DESCRIPTION")
381
+ or auto_description
382
+ or "AI Agent"
383
+ )
384
+ tool_description = (
385
+ args.tool_description or os.getenv("GEMINI_TOOL_DESCRIPTION") or description
386
+ )
387
+ project_id = args.project_id or os.getenv("GOOGLE_CLOUD_PROJECT")
388
+ authorization_id = args.authorization_id or os.getenv("GEMINI_AUTHORIZATION_ID")
389
+
390
+ try:
391
+ register_agent(
392
+ agent_engine_id=agent_engine_id,
393
+ gemini_enterprise_app_id=gemini_enterprise_app_id,
394
+ display_name=display_name,
395
+ description=description,
396
+ tool_description=tool_description,
397
+ project_id=project_id,
398
+ authorization_id=authorization_id,
399
+ )
400
+ except Exception as e:
401
+ print(f"Error during registration: {e}", file=sys.stderr)
402
+ sys.exit(1)
403
+
404
+
405
+ if __name__ == "__main__":
406
+ main()
@@ -204,7 +204,7 @@ def check_and_execute_with_version_lock(
204
204
 
205
205
  try:
206
206
  # Execute uvx with the locked version
207
- cmd = ["uvx", f"agent-starter-pack=={version}", *original_args]
207
+ cmd = ["uvx", f"agent-starter-pack@{version}", *original_args]
208
208
  logging.debug(f"Executing nested command: {' '.join(cmd)}")
209
209
  subprocess.run(cmd, check=True)
210
210
  return True
@@ -71,8 +71,10 @@ def print_deployment_success(
71
71
  location: GCP region where the agent was deployed
72
72
  project: GCP project ID
73
73
  """
74
- # Extract agent engine ID for console URL
75
- agent_engine_id = remote_agent.api_resource.name.split("/")[-1]
74
+ # Extract agent engine ID and project number for console URL
75
+ resource_name_parts = remote_agent.api_resource.name.split("/")
76
+ agent_engine_id = resource_name_parts[-1]
77
+ project_number = resource_name_parts[1]
76
78
  console_url = f"https://console.cloud.google.com/vertex-ai/agents/locations/{location}/agent-engines/{agent_engine_id}?project={project}"
77
79
 
78
80
  {%- if cookiecutter.is_adk %}
@@ -83,12 +85,15 @@ def print_deployment_success(
83
85
  "\n✅ Deployment successful! Test your agent: notebooks/adk_app_testing.ipynb"
84
86
  )
85
87
  {%- endif %}
86
- service_account = remote_agent.api_resource.spec.service_account
87
- print(f"Service Account: {service_account}")
88
- print(f"\n📊 View in console: {console_url}\n")
89
88
  {%- else %}
90
89
  print("\n✅ Deployment successful!")
90
+ {%- endif %}
91
91
  service_account = remote_agent.api_resource.spec.service_account
92
- print(f"Service Account: {service_account}")
92
+ if service_account:
93
+ print(f"Service Account: {service_account}")
94
+ else:
95
+ default_sa = (
96
+ f"service-{project_number}@gcp-sa-aiplatform-re.iam.gserviceaccount.com"
97
+ )
98
+ print(f"Service Account: {default_sa}")
93
99
  print(f"\n📊 View in console: {console_url}\n")
94
- {%- endif %}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agent-starter-pack
3
- Version: 0.17.4
3
+ Version: 0.18.0
4
4
  Summary: CLI to bootstrap production-ready Google Cloud GenAI agent projects from templates.
5
5
  Author-email: Google LLC <agent-starter-pack@google.com>
6
6
  License: Apache-2.0
@@ -11,6 +11,7 @@ Requires-Dist: click>=8.1.7
11
11
  Requires-Dist: cookiecutter<3.0.0,>=2.6.0
12
12
  Requires-Dist: google-cloud-aiplatform>=1.120.0
13
13
  Requires-Dist: pyyaml>=6.0.1
14
+ Requires-Dist: requests>=2.31.0
14
15
  Requires-Dist: rich>=13.7.0
15
16
  Requires-Dist: tomli>=1.1.0; python_version < '3.11'
16
17
  Provides-Extra: jupyter
@@ -45,7 +46,7 @@ Focus on your agent logic—the starter pack provides everything else: infrastru
45
46
 
46
47
  | ⚡️ Launch | 🧪 Experiment | ✅ Deploy | 🛠️ Customize |
47
48
  |---|---|---|---|
48
- | [Pre-built agent templates](./agents/) (ReAct, RAG, multi-agent, Live API). | [Vertex AI evaluation](https://cloud.google.com/vertex-ai/generative-ai/docs/models/evaluation-overview) and an interactive playground. | Production-ready infra with [monitoring, observability](https://googlecloudplatform.github.io/agent-starter-pack/guide/observability), and [CI/CD](https://googlecloudplatform.github.io/agent-starter-pack/guide/deployment) on [Cloud Run](https://cloud.google.com/run) or [Agent Engine](https://cloud.google.com/vertex-ai/generative-ai/docs/agent-engine/overview). | Extend and customize templates according to your needs. 🆕 Now integrating with [Gemini CLI](https://github.com/google-gemini/gemini-cli) |
49
+ | [Pre-built agent templates](./agent_starter_pack/agents/) (ReAct, RAG, multi-agent, Live API). | [Vertex AI evaluation](https://cloud.google.com/vertex-ai/generative-ai/docs/models/evaluation-overview) and an interactive playground. | Production-ready infra with [monitoring, observability](https://googlecloudplatform.github.io/agent-starter-pack/guide/observability), and [CI/CD](https://googlecloudplatform.github.io/agent-starter-pack/guide/deployment) on [Cloud Run](https://cloud.google.com/run) or [Agent Engine](https://cloud.google.com/vertex-ai/generative-ai/docs/agent-engine/overview). | Extend and customize templates according to your needs. 🆕 Now integrating with [Gemini CLI](https://github.com/google-gemini/gemini-cli) |
49
50
 
50
51
  ---
51
52
 
@@ -35,8 +35,8 @@ agent_starter_pack/agents/langgraph_base_react/notebooks/evaluating_langgraph_ag
35
35
  agent_starter_pack/agents/langgraph_base_react/tests/integration/test_agent.py,sha256=xy0A_3eGhxM8A5rc81revMztJN5GtFA-o5-CG5JzeQw,1630
36
36
  agent_starter_pack/base_template/.gitignore,sha256=Fq0w34x4sfbwP4RqDqh6hdHNYRUEsFNI-9XONzLWBIs,2580
37
37
  agent_starter_pack/base_template/GEMINI.md,sha256=ApNsGamVPBsrKeI77p6QxU2-sJE6k3wGwSLVvNa-YGA,126
38
- agent_starter_pack/base_template/Makefile,sha256=cOuwlWgMY1Gr5oBpgH5vZUDx2igM2RRTceEinDcZCww,11765
39
- agent_starter_pack/base_template/README.md,sha256=EqNrXQ9MZAk0fm2wd69bqaoJ-YYhFiAJstB4NYt8KkM,10122
38
+ agent_starter_pack/base_template/Makefile,sha256=rp3abDY_70bChSYM5wpIkPi59LAvneWId36zZ6yNkhY,13017
39
+ agent_starter_pack/base_template/README.md,sha256=MjDtgCPrmkXj70EMv0RkZk7022uljCc0yKLM-l-8ubM,10513
40
40
  agent_starter_pack/base_template/pyproject.toml,sha256=Tc1hPD-o8GtU6YJAkkB2JagTJ5aObdjmjCZuGB4oCb0,3028
41
41
  agent_starter_pack/base_template/deployment/README.md,sha256=gZJvSWdQh_Mi-bZ3dmuPv7fMezIw04fgN5tq7KgglPw,692
42
42
  agent_starter_pack/base_template/deployment/terraform/apis.tf,sha256=KX8Oe2gjT-gh9Bkntz9yIAyRjPc1gZvwOhroJ6NZVp4,1513
@@ -78,7 +78,8 @@ agent_starter_pack/cli/utils/cicd.py,sha256=l9hPdqFXo5SxdtOG1yEoQdmRff5vNcqf0sqx
78
78
  agent_starter_pack/cli/utils/datastores.py,sha256=gv1V6eDcOEKx4MRNG5C3Y-VfixYq1AzQuaYMLp8QRNo,1058
79
79
  agent_starter_pack/cli/utils/gcp.py,sha256=N6pvNU9gT6DpS7Peipfs57ckvqcUWU7OK1zdqBcQV0M,9276
80
80
  agent_starter_pack/cli/utils/logging.py,sha256=61ulUY1hUrpxHDFi0szqsjPlrpxdBvwzfYEEV0o97GA,3530
81
- agent_starter_pack/cli/utils/remote_template.py,sha256=CD5imiJPGIMVRhGOCiB11oFsz9Pusy_A2kdxsvMfscE,24129
81
+ agent_starter_pack/cli/utils/register_gemini_enterprise.py,sha256=KV9loXLjro4ZtSxvQAQ4Jhw4ZPmkLR2MZ3LtMQG6p1o,14865
82
+ agent_starter_pack/cli/utils/remote_template.py,sha256=lWfC1_Vx_m4SD-wVHb8tiGfobOH1-o_eWaM1264rwGs,24128
82
83
  agent_starter_pack/cli/utils/template.py,sha256=9U3eZOqISbCQ-uOmGwLCWagTDjaGPmIKqiei1XiID8w,52459
83
84
  agent_starter_pack/cli/utils/version.py,sha256=F4udQmzniPStqWZFIgnv3Qg3l9non4mfy2An-Oveqmc,2916
84
85
  agent_starter_pack/data_ingestion/README.md,sha256=LNxSQoJW9JozK-TbyGQLj5L_MGWNwrfLk6V6RmQ2oBQ,4032
@@ -96,7 +97,7 @@ agent_starter_pack/deployment_targets/agent_engine/tests/load_test/README.md,sha
96
97
  agent_starter_pack/deployment_targets/agent_engine/tests/load_test/load_test.py,sha256=sZewuwPQwgrfaYCo7IjIhIN9REFXP-rhJbtW236EuGA,9110
97
98
  agent_starter_pack/deployment_targets/agent_engine/tests/load_test/.results/.placeholder,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
98
99
  agent_starter_pack/deployment_targets/agent_engine/{{cookiecutter.agent_directory}}/agent_engine_app.py,sha256=qKEz1z2pD5IpFBq7IhT0GtFpPdbUu54gca10qZKe6Yw,13246
99
- agent_starter_pack/deployment_targets/agent_engine/{{cookiecutter.agent_directory}}/utils/deployment.py,sha256=KwhRqgnTr6JsmVt6BG5zy8wH1sC_mlu5oEgh7L83ERk,3226
100
+ agent_starter_pack/deployment_targets/agent_engine/{{cookiecutter.agent_directory}}/utils/deployment.py,sha256=NdpTwLig1p8jcmpuykacudMYJ7BfpOgvKyD6As6lw1I,3367
100
101
  agent_starter_pack/deployment_targets/agent_engine/{{cookiecutter.agent_directory}}/utils/{% if cookiecutter.is_adk_live %}expose_app.py{% else %}unused_expose_app.py{% endif %},sha256=6o6CBsQblSL919-ag5WcshQBYc3mrIBuyhfxWI0Cmkg,19446
101
102
  agent_starter_pack/deployment_targets/cloud_run/Dockerfile,sha256=GExFR0dSpkTzvzmeE3siGaoXCWp7zKJoB4Uguo0oZhk,1423
102
103
  agent_starter_pack/deployment_targets/cloud_run/deployment/terraform/service.tf,sha256=xBFjT7QGKjMkN2MW40eE22odbyZmvbujkxjAqUN2TNY,11097
@@ -152,12 +153,7 @@ agent_starter_pack/frontends/streamlit/frontend/utils/message_editing.py,sha256=
152
153
  agent_starter_pack/frontends/streamlit/frontend/utils/multimodal_utils.py,sha256=v6YbCkz_YcnEo-9YvRjwBNt0SzU4M39bYxJGmKk69vE,7313
153
154
  agent_starter_pack/frontends/streamlit/frontend/utils/stream_handler.py,sha256=-XVRfLH6ck1KP6NS4vrhcvPyZe6z3NLHliEg17s9jjo,12551
154
155
  agent_starter_pack/frontends/streamlit/frontend/utils/title_summary.py,sha256=B0cadS_KPW-tsbABauI4J681aqjEtuKFDa25e9R1WKc,3030
155
- agent_starter_pack/resources/containers/data_processing/Dockerfile,sha256=VoB9d5yZiiWnqRfWrIq0gGNMzZg-eVy733OgP72ZgO0,950
156
- agent_starter_pack/resources/containers/e2e-tests/Dockerfile,sha256=yA3HxeX0HNpl8B4oEQUICCVZDCXdRn2Igmii4jt-r7k,1895
157
156
  agent_starter_pack/resources/docs/adk-cheatsheet.md,sha256=YSfJd0KER3xkwq6Uy7TC-TaiOdGpj9OrXnvm_wNILdA,71562
158
- agent_starter_pack/resources/idx/idx-template.json,sha256=EuiZ_v__1Zourbz4F8fjutNKNSvLGc6HFRW2_4vVSuM,377
159
- agent_starter_pack/resources/idx/idx-template.nix,sha256=cI35oMmMzgsDRMQgIBmMLtAUczIFramAkA2iBpq_o14,811
160
- agent_starter_pack/resources/idx/.idx/dev.nix,sha256=chSxdz-b06y76Mdbb9zjxUJtI3CN4lBVqiZ0rO7PktE,2356
161
157
  agent_starter_pack/resources/locks/uv-adk_base-agent_engine.lock,sha256=Bmj-6hVfUiS6GDi8_6eHhMAFsmDefxTjrhBeIHOKyOs,588363
162
158
  agent_starter_pack/resources/locks/uv-adk_base-cloud_run.lock,sha256=b4nJ8YTXPp6nQypbA4wz0wNwTH318qOUbfMHIiMoOf0,776457
163
159
  agent_starter_pack/resources/locks/uv-adk_live-agent_engine.lock,sha256=tMOwue7BrFYYJUbOaYvjar0xIhrB4wglljVcm-pXTM0,589379
@@ -172,8 +168,8 @@ agent_starter_pack/utils/generate_locks.py,sha256=LwR46w25CV0_ySF_MS9W2vp7S1Nf17
172
168
  agent_starter_pack/utils/lock_utils.py,sha256=vqFHTN7lju9to74MKOmLvz80BA47G0CVkxrd1MyLWYQ,2309
173
169
  agent_starter_pack/utils/watch_and_rebuild.py,sha256=1hMn29eLpVblfvixV9FEo46u8efmnLuRIn-bPrfdW3g,6694
174
170
  llm.txt,sha256=z9FTkAnj3cErCzHj3IES9eB35wW3JGaVsd8a0wA7IMs,15380
175
- agent_starter_pack-0.17.4.dist-info/METADATA,sha256=mt4AxsXueS2RD43q0LrYqOe5daJUR63K3UNDITu50gU,11210
176
- agent_starter_pack-0.17.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
177
- agent_starter_pack-0.17.4.dist-info/entry_points.txt,sha256=QLSX_97UynG0vLpoZ3ePfyCQkaR-g0qglp2b26G4KHQ,71
178
- agent_starter_pack-0.17.4.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
179
- agent_starter_pack-0.17.4.dist-info/RECORD,,
171
+ agent_starter_pack-0.18.0.dist-info/METADATA,sha256=RpChhntaC0gs-hncyXjrYiCSl0W23PmZXCf9Cyz_TZE,11261
172
+ agent_starter_pack-0.18.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
173
+ agent_starter_pack-0.18.0.dist-info/entry_points.txt,sha256=LO_oGmY1IdlFJRF9s7oIL3qdewC8Q9UtmTV6jWVZq3U,180
174
+ agent_starter_pack-0.18.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
175
+ agent_starter_pack-0.18.0.dist-info/RECORD,,
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ agent-starter-pack = agent_starter_pack.cli.main:cli
3
+ agent-starter-pack-register-gemini-enterprise = agent_starter_pack.cli.utils.register_gemini_enterprise:main
@@ -1,27 +0,0 @@
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"
@@ -1,41 +0,0 @@
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/*
@@ -1,64 +0,0 @@
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
- }
@@ -1,6 +0,0 @@
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
- }
@@ -1,25 +0,0 @@
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
- }
@@ -1,2 +0,0 @@
1
- [console_scripts]
2
- agent-starter-pack = agent_starter_pack.cli.main:cli