agent-starter-pack 0.18.2__py3-none-any.whl → 0.21.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. agent_starter_pack/agents/{langgraph_base_react → adk_a2a_base}/.template/templateconfig.yaml +5 -12
  2. agent_starter_pack/agents/adk_a2a_base/README.md +37 -0
  3. agent_starter_pack/{frontends/streamlit/frontend/style/app_markdown.py → agents/adk_a2a_base/app/__init__.py} +3 -23
  4. agent_starter_pack/agents/adk_a2a_base/app/agent.py +70 -0
  5. agent_starter_pack/agents/adk_a2a_base/notebooks/adk_a2a_app_testing.ipynb +583 -0
  6. agent_starter_pack/agents/{crewai_coding_crew/notebooks/evaluating_crewai_agent.ipynb → adk_a2a_base/notebooks/evaluating_adk_agent.ipynb} +163 -199
  7. agent_starter_pack/agents/adk_a2a_base/tests/integration/test_agent.py +58 -0
  8. agent_starter_pack/agents/adk_base/app/__init__.py +2 -2
  9. agent_starter_pack/agents/adk_base/app/agent.py +3 -0
  10. agent_starter_pack/agents/adk_base/notebooks/adk_app_testing.ipynb +13 -28
  11. agent_starter_pack/agents/adk_live/app/__init__.py +17 -0
  12. agent_starter_pack/agents/adk_live/app/agent.py +3 -0
  13. agent_starter_pack/agents/agentic_rag/app/__init__.py +2 -2
  14. agent_starter_pack/agents/agentic_rag/app/agent.py +3 -0
  15. agent_starter_pack/agents/agentic_rag/notebooks/adk_app_testing.ipynb +13 -28
  16. agent_starter_pack/agents/{crewai_coding_crew → langgraph_base}/.template/templateconfig.yaml +12 -9
  17. agent_starter_pack/agents/langgraph_base/README.md +30 -0
  18. agent_starter_pack/agents/langgraph_base/app/__init__.py +17 -0
  19. agent_starter_pack/agents/{langgraph_base_react → langgraph_base}/app/agent.py +4 -4
  20. agent_starter_pack/agents/{langgraph_base_react → langgraph_base}/tests/integration/test_agent.py +1 -1
  21. agent_starter_pack/base_template/.gitignore +4 -2
  22. agent_starter_pack/base_template/Makefile +110 -16
  23. agent_starter_pack/base_template/README.md +97 -12
  24. agent_starter_pack/base_template/deployment/terraform/dev/apis.tf +4 -6
  25. agent_starter_pack/base_template/deployment/terraform/dev/providers.tf +5 -1
  26. agent_starter_pack/base_template/deployment/terraform/dev/variables.tf +5 -3
  27. agent_starter_pack/base_template/deployment/terraform/dev/{% if cookiecutter.is_adk %}telemetry.tf{% else %}unused_telemetry.tf{% endif %} +193 -0
  28. agent_starter_pack/base_template/deployment/terraform/github.tf +16 -9
  29. agent_starter_pack/base_template/deployment/terraform/locals.tf +7 -7
  30. agent_starter_pack/base_template/deployment/terraform/providers.tf +5 -1
  31. agent_starter_pack/base_template/deployment/terraform/sql/completions.sql +138 -0
  32. agent_starter_pack/base_template/deployment/terraform/storage.tf +0 -9
  33. agent_starter_pack/base_template/deployment/terraform/variables.tf +15 -19
  34. agent_starter_pack/base_template/deployment/terraform/{% if cookiecutter.cicd_runner == 'google_cloud_build' %}build_triggers.tf{% else %}unused_build_triggers.tf{% endif %} +20 -22
  35. agent_starter_pack/base_template/deployment/terraform/{% if cookiecutter.is_adk %}telemetry.tf{% else %}unused_telemetry.tf{% endif %} +206 -0
  36. agent_starter_pack/base_template/pyproject.toml +5 -17
  37. agent_starter_pack/base_template/{% if cookiecutter.cicd_runner == 'github_actions' %}.github{% else %}unused_github{% endif %}/workflows/deploy-to-prod.yaml +19 -4
  38. agent_starter_pack/base_template/{% if cookiecutter.cicd_runner == 'github_actions' %}.github{% else %}unused_github{% endif %}/workflows/staging.yaml +36 -11
  39. agent_starter_pack/base_template/{% if cookiecutter.cicd_runner == 'google_cloud_build' %}.cloudbuild{% else %}unused_.cloudbuild{% endif %}/deploy-to-prod.yaml +24 -5
  40. agent_starter_pack/base_template/{% if cookiecutter.cicd_runner == 'google_cloud_build' %}.cloudbuild{% else %}unused_.cloudbuild{% endif %}/staging.yaml +44 -9
  41. agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/app_utils/telemetry.py +96 -0
  42. agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/{utils → app_utils}/typing.py +4 -6
  43. agent_starter_pack/{agents/crewai_coding_crew/app/crew/config/agents.yaml → base_template/{{cookiecutter.agent_directory}}/app_utils/{% if cookiecutter.is_a2a and cookiecutter.agent_name == 'langgraph_base' %}converters{% else %}unused_converters{% endif %}/__init__.py } +9 -23
  44. agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/app_utils/{% if cookiecutter.is_a2a and cookiecutter.agent_name == 'langgraph_base' %}converters{% else %}unused_converters{% endif %}/part_converter.py +138 -0
  45. agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/app_utils/{% if cookiecutter.is_a2a and cookiecutter.agent_name == 'langgraph_base' %}executor{% else %}unused_executor{% endif %}/__init__.py +13 -0
  46. agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/app_utils/{% if cookiecutter.is_a2a and cookiecutter.agent_name == 'langgraph_base' %}executor{% else %}unused_executor{% endif %}/a2a_agent_executor.py +265 -0
  47. agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/app_utils/{% if cookiecutter.is_a2a and cookiecutter.agent_name == 'langgraph_base' %}executor{% else %}unused_executor{% endif %}/task_result_aggregator.py +152 -0
  48. agent_starter_pack/cli/commands/create.py +40 -4
  49. agent_starter_pack/cli/commands/enhance.py +1 -1
  50. agent_starter_pack/cli/commands/register_gemini_enterprise.py +1070 -0
  51. agent_starter_pack/cli/main.py +2 -0
  52. agent_starter_pack/cli/utils/cicd.py +20 -4
  53. agent_starter_pack/cli/utils/template.py +257 -25
  54. agent_starter_pack/deployment_targets/agent_engine/tests/integration/test_agent_engine_app.py +113 -16
  55. agent_starter_pack/deployment_targets/agent_engine/tests/load_test/README.md +2 -2
  56. agent_starter_pack/deployment_targets/agent_engine/tests/load_test/load_test.py +178 -9
  57. agent_starter_pack/deployment_targets/agent_engine/tests/{% if cookiecutter.is_a2a %}helpers.py{% else %}unused_helpers.py{% endif %} +138 -0
  58. agent_starter_pack/deployment_targets/agent_engine/{{cookiecutter.agent_directory}}/agent_engine_app.py +193 -307
  59. agent_starter_pack/deployment_targets/agent_engine/{{cookiecutter.agent_directory}}/app_utils/deploy.py +414 -0
  60. agent_starter_pack/deployment_targets/agent_engine/{{cookiecutter.agent_directory}}/{utils → app_utils}/{% if cookiecutter.is_adk_live %}expose_app.py{% else %}unused_expose_app.py{% endif %} +13 -14
  61. agent_starter_pack/deployment_targets/cloud_run/Dockerfile +4 -1
  62. agent_starter_pack/deployment_targets/cloud_run/deployment/terraform/dev/service.tf +85 -86
  63. agent_starter_pack/deployment_targets/cloud_run/deployment/terraform/service.tf +139 -107
  64. agent_starter_pack/deployment_targets/cloud_run/tests/integration/test_server_e2e.py +228 -12
  65. agent_starter_pack/deployment_targets/cloud_run/tests/load_test/README.md +4 -4
  66. agent_starter_pack/deployment_targets/cloud_run/tests/load_test/load_test.py +92 -12
  67. agent_starter_pack/deployment_targets/cloud_run/{{cookiecutter.agent_directory}}/{server.py → fast_api_app.py} +194 -121
  68. agent_starter_pack/frontends/adk_live_react/frontend/package-lock.json +18 -18
  69. agent_starter_pack/frontends/adk_live_react/frontend/src/multimodal-live-types.ts +5 -3
  70. agent_starter_pack/resources/docs/adk-cheatsheet.md +198 -41
  71. agent_starter_pack/resources/locks/uv-adk_a2a_base-agent_engine.lock +4966 -0
  72. agent_starter_pack/resources/locks/uv-adk_a2a_base-cloud_run.lock +5011 -0
  73. agent_starter_pack/resources/locks/uv-adk_base-agent_engine.lock +1443 -709
  74. agent_starter_pack/resources/locks/uv-adk_base-cloud_run.lock +1058 -874
  75. agent_starter_pack/resources/locks/uv-adk_live-agent_engine.lock +1443 -709
  76. agent_starter_pack/resources/locks/uv-adk_live-cloud_run.lock +1058 -874
  77. agent_starter_pack/resources/locks/uv-agentic_rag-agent_engine.lock +1568 -749
  78. agent_starter_pack/resources/locks/uv-agentic_rag-cloud_run.lock +1123 -929
  79. agent_starter_pack/resources/locks/{uv-langgraph_base_react-agent_engine.lock → uv-langgraph_base-agent_engine.lock} +1714 -1689
  80. agent_starter_pack/resources/locks/{uv-langgraph_base_react-cloud_run.lock → uv-langgraph_base-cloud_run.lock} +1285 -2374
  81. agent_starter_pack/utils/watch_and_rebuild.py +1 -1
  82. {agent_starter_pack-0.18.2.dist-info → agent_starter_pack-0.21.0.dist-info}/METADATA +3 -6
  83. {agent_starter_pack-0.18.2.dist-info → agent_starter_pack-0.21.0.dist-info}/RECORD +89 -93
  84. agent_starter_pack-0.21.0.dist-info/entry_points.txt +2 -0
  85. llm.txt +4 -5
  86. agent_starter_pack/agents/crewai_coding_crew/README.md +0 -34
  87. agent_starter_pack/agents/crewai_coding_crew/app/agent.py +0 -47
  88. agent_starter_pack/agents/crewai_coding_crew/app/crew/config/tasks.yaml +0 -37
  89. agent_starter_pack/agents/crewai_coding_crew/app/crew/crew.py +0 -71
  90. agent_starter_pack/agents/crewai_coding_crew/tests/integration/test_agent.py +0 -47
  91. agent_starter_pack/agents/langgraph_base_react/README.md +0 -9
  92. agent_starter_pack/agents/langgraph_base_react/notebooks/evaluating_langgraph_agent.ipynb +0 -1574
  93. agent_starter_pack/base_template/deployment/terraform/dev/log_sinks.tf +0 -69
  94. agent_starter_pack/base_template/deployment/terraform/log_sinks.tf +0 -79
  95. agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/utils/tracing.py +0 -155
  96. agent_starter_pack/cli/utils/register_gemini_enterprise.py +0 -406
  97. agent_starter_pack/deployment_targets/agent_engine/deployment/terraform/{% if not cookiecutter.is_adk_live %}service.tf{% else %}unused_service.tf{% endif %} +0 -82
  98. agent_starter_pack/deployment_targets/agent_engine/notebooks/intro_agent_engine.ipynb +0 -1025
  99. agent_starter_pack/deployment_targets/agent_engine/{{cookiecutter.agent_directory}}/utils/deployment.py +0 -99
  100. agent_starter_pack/frontends/streamlit/frontend/side_bar.py +0 -214
  101. agent_starter_pack/frontends/streamlit/frontend/streamlit_app.py +0 -265
  102. agent_starter_pack/frontends/streamlit/frontend/utils/chat_utils.py +0 -67
  103. agent_starter_pack/frontends/streamlit/frontend/utils/local_chat_history.py +0 -127
  104. agent_starter_pack/frontends/streamlit/frontend/utils/message_editing.py +0 -59
  105. agent_starter_pack/frontends/streamlit/frontend/utils/multimodal_utils.py +0 -217
  106. agent_starter_pack/frontends/streamlit/frontend/utils/stream_handler.py +0 -310
  107. agent_starter_pack/frontends/streamlit/frontend/utils/title_summary.py +0 -94
  108. agent_starter_pack/resources/locks/uv-crewai_coding_crew-agent_engine.lock +0 -6650
  109. agent_starter_pack/resources/locks/uv-crewai_coding_crew-cloud_run.lock +0 -7825
  110. agent_starter_pack-0.18.2.dist-info/entry_points.txt +0 -3
  111. /agent_starter_pack/agents/{crewai_coding_crew → langgraph_base}/notebooks/evaluating_langgraph_agent.ipynb +0 -0
  112. /agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/{utils → app_utils}/gcs.py +0 -0
  113. {agent_starter_pack-0.18.2.dist-info → agent_starter_pack-0.21.0.dist-info}/WHEEL +0 -0
  114. {agent_starter_pack-0.18.2.dist-info → agent_starter_pack-0.21.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,406 +0,0 @@
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()
@@ -1,82 +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
- # Get project information to access the project number
16
- data "google_project" "project" {
17
- for_each = local.deploy_project_ids
18
-
19
- project_id = local.deploy_project_ids[each.key]
20
- }
21
-
22
- resource "google_vertex_ai_reasoning_engine" "app_staging" {
23
- display_name = var.project_name
24
- description = "Agent deployed via Terraform"
25
- region = var.region
26
- project = var.staging_project_id
27
-
28
- spec {
29
- service_account = google_service_account.app_sa["staging"].email
30
-
31
- package_spec {
32
- # IMPORTANT: This Python version must match the version used in CI/CD pipelines
33
- # for pickling compatibility. Mismatched versions will cause deserialization errors.
34
- python_version = "3.12"
35
- pickle_object_gcs_uri = "gs://agent-starter-pack/dummy/agent_engine.pkl"
36
- dependency_files_gcs_uri = "gs://agent-starter-pack/dummy/dependencies.tar.gz"
37
- requirements_gcs_uri = "gs://agent-starter-pack/dummy/requirements.txt"
38
- }
39
- }
40
-
41
- # This lifecycle block prevents Terraform from overwriting the spec when it's
42
- # updated by Agent Engine deployments outside of Terraform (e.g., via CI/CD pipelines)
43
- lifecycle {
44
- ignore_changes = [
45
- spec,
46
- ]
47
- }
48
-
49
- # Make dependencies conditional to avoid errors.
50
- depends_on = [google_project_service.deploy_project_services]
51
- }
52
-
53
- resource "google_vertex_ai_reasoning_engine" "app_prod" {
54
- display_name = var.project_name
55
- description = "Agent deployed via Terraform"
56
- region = var.region
57
- project = var.prod_project_id
58
-
59
- spec {
60
- service_account = google_service_account.app_sa["prod"].email
61
-
62
- package_spec {
63
- # IMPORTANT: This Python version must match the version used in CI/CD pipelines
64
- # for pickling compatibility. Mismatched versions will cause deserialization errors.
65
- python_version = "3.12"
66
- pickle_object_gcs_uri = "gs://agent-starter-pack/dummy/agent_engine.pkl"
67
- dependency_files_gcs_uri = "gs://agent-starter-pack/dummy/dependencies.tar.gz"
68
- requirements_gcs_uri = "gs://agent-starter-pack/dummy/requirements.txt"
69
- }
70
- }
71
-
72
- # This lifecycle block prevents Terraform from overwriting the spec when it's
73
- # updated by Agent Engine deployments outside of Terraform (e.g., via CI/CD pipelines)
74
- lifecycle {
75
- ignore_changes = [
76
- spec,
77
- ]
78
- }
79
-
80
- # Make dependencies conditional to avoid errors.
81
- depends_on = [google_project_service.deploy_project_services]
82
- }