Chapter 25
Intro to Managed Agents API on Agent Platform (Python)
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.Intro to Managed Agents API on Agent Platform (Python)
| Authors |
|---|
| Eric Schmidt |
Overview
This notebook demonstrates operations for Managed Agents API on Gemini Enterprise Agent Platform using the Gen AI SDK for Python.
Covering:
- Managed Agents API: Create, list, get, and delete custom agents
- Interactions API: Interact with Antigravity (1P) and custom agents
- Environment Features: Session state management, MCP tools, skills
Note: The Managed Agents API is in Preview.
- Features and schemas are subject to change.
- They are not intended for production applications.
- It is highly recommended to run this sample in an isolated development or testing project.
For complete Manged Agents API documentation please visit: https://docs.cloud.google.com/gemini-enterprise-agent-platform/build/managed-agents.
Getting Started
Install Gen AI SDK for Python
%pip install --upgrade --quiet "google-genai>=2.0.0"⚠️ Note: Ignore pip dependency errors.
Import Libraries
import os
import sys
import requests
from google import genaiAuthenticate your Notebook Environment
If you are running this notebook in Google Colab, execute the cell below to authenticate.
if "google.colab" in sys.modules:
from google.colab import auth
auth.authenticate_user()Set Google Cloud Project Information
To get started using Agent Platform, you must have an existing Google Cloud project and enable the Agent Platform API.
Learn more about setting up a project and a development environment.
# fmt: off
PROJECT_ID = "" # @param {type: "string", placeholder: "[your-project-id]", isTemplate: true}
# fmt: on
if not PROJECT_ID or PROJECT_ID == "[your-project-id]":
PROJECT_ID = str(os.getenv("GOOGLE_CLOUD_PROJECT"))
LOCATION = "global"
client = genai.Client(enterprise=True, project=PROJECT_ID, location=LOCATION)Project Validation
Before provisioning agents or starting conversations, verify that your Google Cloud project and permissions meet the platform requirements.
The following diagnostic helper validates:
- Authentication: Confirms active Application Default Credentials (ADC).
- API Enablement: Verifies
aiplatform.googleapis.comis enabled. - Service Account Role: Confirms the Google-managed AI Platform service agent has the
roles/aiplatform.serviceAgentrole (required for container sandbox and GCS bucket orchestration). - User Access: Confirms your identity is authorized with
roles/aiplatform.user,roles/aiplatform.admin, orroles/owner.
[!NOTE] If any check fails, the diagnostic helper will print specific commands to resolve the issue.
def check_project_settings(project_id: str) -> None:
"""Validates GCP project settings, APIs, and IAM roles for AI Platform."""
# Extract Token
printed_token = !gcloud auth application-default print-access-token
token = printed_token[0] if printed_token else None
if token:
print("✅ Success on token creation.")
else:
print("❌ Token creation failed.")
return
# Extract project number
project_info_response = !gcloud projects describe {project_id} --format="value(projectNumber)"
if not project_info_response:
print("❌ Failed to retrieve project number.")
return
project_number = project_info_response[0]
print(f"✅ The project number for {project_id} is: {project_number}")
# Is aiplatform enabled
api_name = "aiplatform.googleapis.com"
result = !gcloud services list --project={project_id} --enabled --filter="name:{api_name}" --format="value(name)"
if any(api_name in service for service in result):
print(f"✅ {api_name} is enabled.")
else:
print(f"❌ {api_name} is NOT enabled. You may need to run:")
print(f" !gcloud services enable {api_name} --project={project_id}")
# Does service account have needed bindings
sa_email = f"service-{project_number}@gcp-sa-aiplatform.iam.gserviceaccount.com"
sa_info_response = !gcloud projects get-iam-policy {project_id} \
--flatten="bindings[].members" \
--filter="bindings.members:serviceAccount:{sa_email}" \
--format="value(bindings.role)"
if any("aiplatform.serviceAgent" in role for role in sa_info_response):
print("✅ The service account has the aiplatform.serviceAgent role.")
else:
print("❌ The service account does NOT have the aiplatform.serviceAgent role.")
print("Attempting to add role...")
attempt_add_role = !gcloud projects add-iam-policy-binding {project_id} \
--member="serviceAccount:{sa_email}" \
--role="roles/aiplatform.serviceAgent"
# Extract email from token
email = None
try:
token_info_response = requests.get(f"https://oauth2.googleapis.com/tokeninfo?access_token={token}", timeout=10)
if token_info_response.status_code == 200:
data = token_info_response.json()
# The email will only be present if the "userinfo.email" scope was requested
email = data.get("email")
print(f"Token belongs to: {email}")
else:
print("Invalid or expired token.")
return
except requests.RequestException as e:
print(f"Failed to reach tokeninfo API: {e}")
return
if not email:
print("Email scope not requested; cannot verify user IAM roles.")
return
# Does user have needed bindings
user_roles_response = !gcloud projects get-iam-policy {project_id} \
--flatten="bindings[].members" \
--filter="bindings.members:user:{email}" \
--format="value(bindings.role)"
print(f"Raw roles found: {user_roles_response}")
if not user_roles_response:
print(f"❌ The user {email} has no direct project-level roles assigned.")
return
# Check for owner, admin, and user roles
is_owner = any("roles/owner" in role for role in user_roles_response)
is_ai_admin = any("aiplatform.admin" in role for role in user_roles_response)
is_ai_user = any("aiplatform.user" in role for role in user_roles_response)
if is_owner:
print(f"✅ The user {email} is a project Owner, which inherits all AI Platform permissions.")
elif is_ai_admin:
print(f"✅ The user {email} has the explicit aiplatform.admin role.")
elif is_ai_user:
print(f"✅ The user {email} has the explicit aiplatform.user role (standard user access).")
else:
print(f"❌ The user {email} does NOT have the aiplatform.admin, aiplatform.user, or owner role.")
check_project_settings(PROJECT_ID)Output
✅ Success on token creation. ✅ The project number for cloude-sandbox is: 706124400321 ✅ aiplatform.googleapis.com is enabled. ✅ The service account has the aiplatform.serviceAgent role. Token belongs to: cloude@google.com Raw roles found: ['roles/cloudaicompanion.user', 'roles/developerconnect.admin', 'roles/mcp.toolUser', 'roles/ml.admin', 'roles/owner'] ✅ The user cloude@google.com is a project Owner, which inherits all AI Platform permissions.
Create a Google Cloud Storage Bucket
To demonstrate mounting remote workspace directories into an agent container, you need a target Google Cloud Storage (GCS) bucket.
Create new bucket that you will use for testing.
The following cell programmatically provisions a new GCS bucket using the gcloud CLI. This bucket will be mounted as a local workspace path when creating your custom agent in the next step.
AGENT_GCS_BUCKET = "" # @param {type:"string"}
create_response = !gcloud storage buckets create gs://{AGENT_GCS_BUCKET} --project={PROJECT_ID}
print(create_response)Output
['Creating gs://eric-agent-demo-bucket-002/...']
Managed Agents API — Create, List, Get, Delete
The Managed Agents API serves as the Control Plane of the platform. It allows you to provision, configure, retrieve, and manage stateful, reusable agent resources that persist securely within your Google Cloud project.
Each custom agent is defined by extending a base_agent (such as antigravity-preview-05-2026) and configuring:
- System Instructions: Tailor the agent's expertise and behavior policies.
- Built-in Tools: Enable local capabilities like code execution, filesystem operations, or Google Search.
- Workspace Mounts: Attach Google Cloud Storage (GCS) directories as sandboxed local paths.
- Third-Party Integrations: Connect secure Model Context Protocol (MCP) servers.
- Skill Registries: Mount reusable domain-expert instructions from the platform's Skill Registry.
1. Create a Custom Agent with GCS Mount and Default Tools
To start, create a custom agent resource. This agent will extend the foundational base agent with a targeted system instruction, enable built-in developer tools, and mount your Google Cloud Storage (GCS) bucket as a local directory path in its sandboxed environment.
import uuid
AGENT_ID = f"sdk-demo-agent-{uuid.uuid4().hex[:8]}"
agent = client.agents.create(
id=AGENT_ID,
base_agent="antigravity-preview-05-2026",
description="A demo agent created with the Python SDK.",
system_instruction="You are a helpful coding assistant. Write clean, well-documented Python code.",
tools=[
{"type": "code_execution"},
{"type": "google_search"},
{"type": "url_context"},
],
base_environment={
"type": "remote",
"sources": [
{
"type": "gcs",
"source": "gs://"+AGENT_GCS_BUCKET,
"target": "/.agent",
}
],
"network": {
"allowlist": [{"domain": "*"}]
},
},
)
# Note: Agent creation is an asynchronous
# You can poll creation status by calling client.agents.get()
print(f"Agent created: {AGENT_ID}")
print(agent)Output
Agent created: sdk-demo-agent-743bb998
Agent(id=None, base_agent=None, base_environment=None, description=None, system_instruction=None, tools=None, name='projects/706124400321/locations/global/agents/sdk-demo-agent-743bb998/operations/7667486117737791488', metadata={'@type': 'type.googleapis.com/google.cloud.aiplatform.v1beta1.CreateAgentOperationMetadata', 'genericMetadata': {'createTime': '2026-05-19T17:30:38.649097Z', 'updateTime': '2026-05-19T17:30:38.649097Z'}})
Option A: Create an Agent with Model Context Protocol (MCP) Tools
You can extend an agent's toolsuite beyond standard built-in tools by linking secure, remote Model Context Protocol (MCP) servers. Under the tools payload, supply a target dictionary containing the URL of your MCP server and any mandatory security headers required for authentication.
import time
print(f"SDK version: {genai.__version__}")
print(f"Project: {PROJECT_ID}")
print(f"Location: {LOCATION}")
MCP_AGENT_ID = f"mcp-agent-{uuid.uuid4().hex[:8]}"
mcp_agent = client.agents.create(
id=MCP_AGENT_ID,
base_agent="antigravity-preview-05-2026",
description="An agent with MCP tool access for code search.",
system_instruction="You are a helpful assistant with access to code search tools.",
tools=[
{
"type": "mcp_server",
"name": "grep-search",
"url": "https://mcp.grep.app",
}
],
)
print(f"MCP Agent created: {MCP_AGENT_ID}")
print(mcp_agent)
time.sleep(10)
response = client.agents.list()
if response.agents:
print(f"Found {len(response.agents)} agent(s):\n")
for i, a in enumerate(response.agents, 1):
print(f" [{i}] {a.id}")
print(f" Base Agent: {a.base_agent or '—'}")
print(f" Description: {a.description or '—'}")
tools_str = ", ".join(t.type for t in a.tools) if a.tools else "None"
print(f" Tools: {tools_str}")
print()
if response.next_page_token:
print(f"More results available (next_page_token: {response.next_page_token})")
else:
print("No agents found.")Output
SDK version: 2.4.0
Project: cloude-sandbox
Location: global
MCP Agent created: mcp-agent-65788712
Agent(id=None, base_agent=None, base_environment=None, description=None, system_instruction=None, tools=None, name='projects/706124400321/locations/global/agents/mcp-agent-65788712/operations/592331103138742272', metadata={'@type': 'type.googleapis.com/google.cloud.aiplatform.v1beta1.CreateAgentOperationMetadata', 'genericMetadata': {'createTime': '2026-05-19T17:30:43.659264Z', 'updateTime': '2026-05-19T17:30:43.659264Z'}})
Found 2 agent(s):
[1] mcp-agent-65788712
Base Agent: antigravity-preview-05-2026
Description: An agent with MCP tool access for code search.
Tools: mcp_server
[2] world-cup-agent-demo-1
Base Agent: antigravity-preview-05-2026
Description: A demo agent showcasing Environment and GCS use case.
Tools: filesystem, google_search
Option B: Mount Skills from the Skill Registry
To build highly specialized domain-expert agents, you can mount structured instruction packages directly from your central Skill Registry. By referencing the unique registered skill name, the agent will dynamically discover and parse its instructions.
NOTE: Replace
SKILL_RESOURCE_NAMEwith an actual skill path from your project. Example:projects/your-project/locations/us-central1/skills/your-skill
SKILL_AGENT_ID = f"skill-agent-{uuid.uuid4().hex[:8]}"
SKILL_RESOURCE_NAME = "projects/your-project/locations/us-central1/skills/your-skill" # @param {type:"string"}
skill_agent = client.agents.create(
id=SKILL_AGENT_ID,
base_agent="antigravity-preview-05-2026",
base_environment={
"type": "remote",
"sources": [
{
"type": "skill_registry",
"source": SKILL_RESOURCE_NAME,
"target": "./skills",
}
],
"network": {
"allowlist": [{"domain": "*"}]
},
},
)
print(f"Skill agent created: {SKILL_AGENT_ID}")
print(skill_agent)Create a GCS Bucket to Stage Skill Packages
Create a dedicated Google Cloud Storage bucket to host and serve raw skill packages for your custom agents.
AGENT_GCS_BUCKET = "" # @param {type:"string"}
create_response = !gcloud storage buckets create gs://{AGENT_GCS_BUCKET} --project={PROJECT_ID}
print(create_response)Option C: Mount Skill Packages from a GCS Path
Alternatively, you can configure an agent to dynamically load raw skill packages stored directly inside a Google Cloud Storage (GCS) directory. This lets you stage and test new skills directly from cloud storage without having to register them in the central Skill Registry first.
AGENT_SKILL_GCS_BUCKET = "" # @param {type:"string"}
create_response = !gcloud storage buckets create gs://{AGENT_SKILL_GCS_BUCKET} --project={PROJECT_ID}
print(create_response)
GCS_SKILL_AGENT_ID = f"gcs-skill-agent-{uuid.uuid4().hex[:8]}"
gcs_skill_agent = client.agents.create(
id=GCS_SKILL_AGENT_ID,
base_agent="antigravity-preview-05-2026",
base_environment={
"type": "remote",
"sources": [
{
"type": "gcs",
"source": "gs://"+AGENT_SKILL_GCS_BUCKET,
"target": "./skills",
}
],
"network": {
"allowlist": [{"domain": "*"}]
},
},
)
print(f"GCS skill agent created: {GCS_SKILL_AGENT_ID}")
print(gcs_skill_agent)Output
['Creating gs://agent-demo-skills-0001/...', '\x1b[1;31mERROR:\x1b[0m (gcloud.storage.buckets.create) HTTPError 409: Your previous request to create the named bucket succeeded and you already own it.']
GCS skill agent created: gcs-skill-agent-e27f0d77
Agent(id=None, base_agent=None, base_environment=None, description=None, system_instruction=None, tools=None, name='projects/706124400321/locations/global/agents/gcs-skill-agent-e27f0d77/operations/7509860130779824128', metadata={'@type': 'type.googleapis.com/google.cloud.aiplatform.v1beta1.CreateAgentOperationMetadata', 'genericMetadata': {'createTime': '2026-05-19T17:31:04.319570Z', 'updateTime': '2026-05-19T17:31:04.319570Z'}})
3. List Registered Agents
Retrieve a list of all custom agents provisioned and configured under your target Google Cloud project.
response = client.agents.list()
if response.agents:
print(f"Found {len(response.agents)} agent(s):\n")
for i, a in enumerate(response.agents, 1):
print(f" [{i}] {a.id}")
print(f" Base Agent: {a.base_agent or '—'}")
print(f" Description: {a.description or '—'}")
tools_str = ", ".join(t.type for t in a.tools) if a.tools else "None"
print(f" Tools: {tools_str}")
print()
if response.next_page_token:
print(f"More results available (next_page_token: {response.next_page_token})")
else:
print("No agents found.")Output
Found 4 agent(s):
[1] gcs-skill-agent-e27f0d77
Base Agent: antigravity-preview-05-2026
Description: —
Tools: None
[2] mcp-agent-65788712
Base Agent: antigravity-preview-05-2026
Description: An agent with MCP tool access for code search.
Tools: mcp_server
[3] sdk-demo-agent-743bb998
Base Agent: antigravity-preview-05-2026
Description: A demo agent created with the Python SDK.
Tools: code_execution, google_search, url_context
[4] world-cup-agent-demo-1
Base Agent: antigravity-preview-05-2026
Description: A demo agent showcasing Environment and GCS use case.
Tools: filesystem, google_search
4. Retrieve a Specific Agent Config
Query the control plane using a specific agent_id to inspect its display name, active system instructions, mounted environments, or enabled tool configurations.
agent_details = client.agents.get(id=AGENT_ID)
print(f"Agent ID: {agent_details.id}")
print(f"Base Agent: {agent_details.base_agent}")
print(f"Description: {agent_details.description}")
print(f"System Instruction: {agent_details.system_instruction[:100] if agent_details.system_instruction else '—'}...")
print(f"Tools: {[t.type for t in agent_details.tools] if agent_details.tools else 'None'}")
print(f"Environment: {agent_details.base_environment}")Update agent (REST only)
Note: The
agents.update()method is not yet available in the Python SDK. To update an agent's configuration (system instruction, tools, environment, skills), use the REST API with aPATCHrequest andupdate_mask.See the Update an agent documentation for REST examples.
Interactions API — Interact with Agents
The Interactions API is the data plane for communicating with agents at runtime. It supports streaming responses, environment management, and dynamic tool overrides.
1. Interact with the Foundational Base Agent
You can stream conversational interactions directly against the platform's pre-configured foundational base_agent (e.g., antigravity-preview-05-2026) without establishing a custom agent profile first.
stream = client.interactions.create(
agent="antigravity-preview-05-2026",
input="Who are you? Can you execute Python code? Show me an example.",
environment={"type": "remote"},
stream=True,
background=True,
store=True
)
print("Antigravity Agent Response (streaming):")
print("=" * 60)
for event in stream:
print(event)Output
Antigravity Agent Response (streaming):
============================================================
InteractionCreatedEvent(event_type='interaction.created', interaction=Interaction(id='ChA3YjRhMWNhMzYyZjk0MWZiEAgaAzAxNioEbWFpbg', created=None, status='in_progress', steps=None, updated=None, agent=None, agent_config=None, environment=None, environment_id=None, input=None, model=None, previous_interaction_id=None, response_format=None, response_mime_type=None, response_modalities=None, role=None, service_tier=None, system_instruction=None, tools=None, usage=None, webhook_config=None, object='interaction'), event_id=None)
InteractionStatusUpdate(event_type='interaction.status_update', interaction_id='ChA3YjRhMWNhMzYyZjk0MWZiEAgaAzAxNioEbWFpbg', status='in_progress', event_id=None)
StepStart(event_type='step.start', index=0, step=FunctionCallStep(id='f9f027a2-a0a7-4a79-b843-7eb5063528eb', arguments={}, name='run_command', type='function_call', signature=None), event_id=None)
StepDelta(delta=DeltaArgumentsDelta(type='arguments_delta', arguments='{"toolSummary":"Python execution test","explanation":"Executed a Python one-liner to demonstrate execution capabilities and print the Python version.","Cwd":"/workspace","CommandLine":"python3 -c \\"import sys; print(f\'Hello from Python {sys.version}!\')\\"","toolAction":"Running python command","WaitMsBeforeAsync":5000}'), event_type='step.delta', index=0, event_id=None)
StepStop(event_type='step.stop', index=0, event_id=None)
StepStart(event_type='step.start', index=1, step=FunctionResultStep(call_id='f9f027a2-a0a7-4a79-b843-7eb5063528eb', result=None, type='function_result', is_error=None, name='run_command', signature=''), event_id=None)
StepDelta(delta=DeltaFunctionResult(call_id=None, result={'Output': '[STDOUT]\nHello from Python 3.11.15 (main, Mar 3 2026, 09:26:23) [GCC 11.4.0]!\n\n\n[STDERR]\n', 'ExitCode': 0}, type='function_result', is_error=False, name='run_command'), event_type='step.delta', index=1, event_id=None)
StepStop(event_type='step.stop', index=1, event_id=None)
StepStart(event_type='step.start', index=2, step=ModelOutputStep(type='model_output', content=None), event_id=None)
StepDelta(delta=DeltaText(text='I am Antigravity, a powerful agentic', type='text'), event_type='step.delta', index=2, event_id=None)
StepDelta(delta=DeltaText(text=' AI assistant designed by Google. \n\nYes, I can execute Python code. Here is an example of running a Python command in', type='text'), event_type='step.delta', index=2, event_id=None)
StepDelta(delta=DeltaText(text=' my environment:\n\n```python\nimport sys\nprint(f"Hello from Python {sys.version}!")\n```\n\n**Output', type='text'), event_type='step.delta', index=2, event_id=None)
StepDelta(delta=DeltaText(text=':**\n```text\nHello from Python 3.11.15 (main, Mar 3 2026,', type='text'), event_type='step.delta', index=2, event_id=None)
StepDelta(delta=DeltaText(text=' 09:26:23) [GCC 11.4.0]!\n```\n\n', type='text'), event_type='step.delta', index=2, event_id=None)
StepDelta(delta=DeltaText(text='***\n\n**Summary of work:**\n- Discovered and verified Python execution environment.\n- Demonstrated Python execution capability with a simple', type='text'), event_type='step.delta', index=2, event_id=None)
StepDelta(delta=DeltaText(text=' system version query.', type='text'), event_type='step.delta', index=2, event_id=None)
StepStop(event_type='step.stop', index=2, event_id=None)
InteractionCompletedEvent(event_type='interaction.completed', interaction=Interaction(id='ChA3YjRhMWNhMzYyZjk0MWZiEAgaAzAxNioEbWFpbg', created=datetime.datetime(2026, 5, 19, 17, 31, 24, tzinfo=datetime.timezone.utc), status='completed', steps=None, updated=datetime.datetime(2026, 5, 19, 17, 31, 24, tzinfo=datetime.timezone.utc), agent=None, agent_config=None, environment=None, environment_id='env_CAEQgICAgIDQyN1tGiBjZDNkZmNmZDU2N2U0NDRhODk1ZjNjYmIwMDYwZDc1Yg', input=None, model=None, previous_interaction_id=None, response_format=None, response_mime_type=None, response_modalities=None, role=None, service_tier=None, system_instruction=None, tools=None, usage=Usage(cached_tokens_by_modality=None, grounding_tool_count=None, input_tokens_by_modality=[InputTokensByModality(modality='text', tokens=13222)], output_tokens_by_modality=[OutputTokensByModality(modality='text', tokens=267)], tool_use_tokens_by_modality=None, total_cached_tokens=None, total_input_tokens=13222, total_output_tokens=267, total_thought_tokens=1181, total_tokens=14670, total_tool_use_tokens=None), webhook_config=None, object='interaction'), event_id=None)
2. Interact with your Custom Agent
Execute stateful, multi-turn conversations against the custom agent you provisioned on the control plane. This request automatically invokes all mounted capabilities, system instructions, and customized tool suites.
stream = client.interactions.create(
agent=AGENT_ID,
input="Tell me the name of python packages used for data analysis.",
stream=True,
background=True,
store=True,
)
print(f"Custom Agent ({AGENT_ID}) Response:")
print("=" * 60)
for event in stream:
print(event)Output
Custom Agent (sdk-demo-agent-743bb998) Response:
============================================================
InteractionCreatedEvent(event_type='interaction.created', interaction=Interaction(id='ChA2NWFjMmM0YjIxOGEyYzQ5EAgaAzBkYioEbWFpbg', created=None, status='in_progress', steps=None, updated=None, agent=None, agent_config=None, environment=None, environment_id=None, input=None, model=None, previous_interaction_id=None, response_format=None, response_mime_type=None, response_modalities=None, role=None, service_tier=None, system_instruction=None, tools=None, usage=None, webhook_config=None, object='interaction'), event_id=None)
InteractionStatusUpdate(event_type='interaction.status_update', interaction_id='ChA2NWFjMmM0YjIxOGEyYzQ5EAgaAzBkYioEbWFpbg', status='in_progress', event_id=None)
StepStart(event_type='step.start', index=0, step=FunctionCallStep(id='44997a6a-e562-4927-832f-964a9bd5adb2', arguments={}, name='list_dir', type='function_call', signature=None), event_id=None)
StepDelta(delta=DeltaArgumentsDelta(type='arguments_delta', arguments='{"toolAction":"Listing directory","explanation":"Listing the contents of /workspace to understand the environment and see if any skill files or local files exist.","toolSummary":"Directory listing","DirectoryPath":"/workspace"}'), event_type='step.delta', index=0, event_id=None)
StepStop(event_type='step.stop', index=0, event_id=None)
StepStart(event_type='step.start', index=1, step=FunctionResultStep(call_id='44997a6a-e562-4927-832f-964a9bd5adb2', result=None, type='function_result', is_error=None, name='list_dir', signature=''), event_id=None)
StepDelta(delta=DeltaFunctionResult(call_id=None, result={'results': None}, type='function_result', is_error=False, name='list_dir'), event_type='step.delta', index=1, event_id=None)
StepStop(event_type='step.stop', index=1, event_id=None)
StepStart(event_type='step.start', index=2, step=ModelOutputStep(type='model_output', content=None), event_id=None)
StepDelta(delta=DeltaText(text='Here are some of the most popular and widely used Python packages for', type='text'), event_type='step.delta', index=2, event_id=None)
StepDelta(delta=DeltaText(text=' data analysis, categorized by their primary function:\n\n### 1. Data Manipulation and Preparation\n* **Pandas', type='text'), event_type='step.delta', index=2, event_id=None)
StepDelta(delta=DeltaText(text='**: The industry-standard library for data manipulation and analysis. It introduces the `DataFrame` structure, which makes handling tabular', type='text'), event_type='step.delta', index=2, event_id=None)
StepDelta(delta=DeltaText(text=', time-series, and structured data extremely easy.\n* **NumPy**: The foundational package for scientific computing in Python. It provides', type='text'), event_type='step.delta', index=2, event_id=None)
StepDelta(delta=DeltaText(text=' highly optimized support for large, multi-dimensional arrays and matrices, along with a collection of mathematical functions.\n* **', type='text'), event_type='step.delta', index=2, event_id=None)
StepDelta(delta=DeltaText(text='Polars**: A lightning-fast, multi-threaded DataFrame library written in Rust, designed to handle large datasets more efficiently than Pandas', type='text'), event_type='step.delta', index=2, event_id=None)
StepDelta(delta=DeltaText(text='.\n\n### 2. Data Visualization\n* **Matplotlib**: The core, highly customizable plotting library in Python used to', type='text'), event_type='step.delta', index=2, event_id=None)
StepDelta(delta=DeltaText(text=' create static, animated, and interactive visualizations.\n* **Seaborn**: Built on top of Matplotlib,', type='text'), event_type='step.delta', index=2, event_id=None)
StepDelta(delta=DeltaText(text=' it simplifies the process of creating beautiful, informative statistical graphics.\n* **Plotly**: A library for creating interactive, web-ready', type='text'), event_type='step.delta', index=2, event_id=None)
StepDelta(delta=DeltaText(text=' plots and dashboards.\n\n### 3. Statistical Analysis & Machine Learning\n* **SciPy**: Built on NumPy,', type='text'), event_type='step.delta', index=2, event_id=None)
StepDelta(delta=DeltaText(text=' it is used for scientific and technical computing, including integration, optimization, signal processing, and statistical distributions.\n* **Stats', type='text'), event_type='step.delta', index=2, event_id=None)
StepDelta(delta=DeltaText(text='models**: Focuses on statistical modeling, hypothesis testing, and exploring data. It is excellent for linear regression, generalized linear models, and time series', type='text'), event_type='step.delta', index=2, event_id=None)
StepDelta(delta=DeltaText(text=' analysis.\n* **Scikit-learn**: The premier machine learning library in Python, featuring tools for data preprocessing', type='text'), event_type='step.delta', index=2, event_id=None)
StepDelta(delta=DeltaText(text=', classification, regression, clustering, and model evaluation.\n\n### 4. Big Data & Parallel Computing\n* **D', type='text'), event_type='step.delta', index=2, event_id=None)
StepDelta(delta=DeltaText(text='ask**: Enables parallel computing and scales Python libraries like NumPy, Pandas, and Scikit-learn to work on larger-', type='text'), event_type='step.delta', index=2, event_id=None)
StepDelta(delta=DeltaText(text='than-memory datasets.\n* **PySpark**: The Python API for Apache Spark, used for processing massive datasets', type='text'), event_type='step.delta', index=2, event_id=None)
StepDelta(delta=DeltaText(text=' across distributed clusters.\n\n---\n\n### Summary of Work\n* Identified and categorized the primary Python libraries used in', type='text'), event_type='step.delta', index=2, event_id=None)
StepDelta(delta=DeltaText(text=' data analysis.\n* Provided brief descriptions explaining the specific role of each package (manipulation, visualization, statistical modeling', type='text'), event_type='step.delta', index=2, event_id=None)
StepDelta(delta=DeltaText(text=', and big data).', type='text'), event_type='step.delta', index=2, event_id=None)
StepStop(event_type='step.stop', index=2, event_id=None)
InteractionCompletedEvent(event_type='interaction.completed', interaction=Interaction(id='ChA2NWFjMmM0YjIxOGEyYzQ5EAgaAzBkYioEbWFpbg', created=datetime.datetime(2026, 5, 19, 17, 31, 44, tzinfo=datetime.timezone.utc), status='completed', steps=None, updated=datetime.datetime(2026, 5, 19, 17, 31, 44, tzinfo=datetime.timezone.utc), agent=None, agent_config=None, environment=None, environment_id='env_CAEQgICAgIDQyN1tGiBiZDBlYTE1YTYxNzM0NzkzYWY4N2JlYzJjNmE0Nzk0Ng', input=None, model=None, previous_interaction_id=None, response_format=None, response_mime_type=None, response_modalities=None, role=None, service_tier=None, system_instruction=None, tools=None, usage=Usage(cached_tokens_by_modality=None, grounding_tool_count=None, input_tokens_by_modality=[InputTokensByModality(modality='text', tokens=14665)], output_tokens_by_modality=[OutputTokensByModality(modality='text', tokens=983)], tool_use_tokens_by_modality=None, total_cached_tokens=None, total_input_tokens=14665, total_output_tokens=983, total_thought_tokens=1662, total_tokens=17310, total_tool_use_tokens=None), webhook_config=None, object='interaction'), event_id=None)
Session State with Environment IDs
By default, interactions are stateless. To maintain session state (files, installed packages, execution context) across multiple turns, reuse the environment ID (env_id) returned from the initial interaction.
The sandbox has a 7-day TTL that resets with each new interaction.
Initiate the Session Environment
To maintain conversational state and persist runtime context (like environment variables and local filesystem files), initiate the first interaction with the custom agent. The platform will allocate a dedicated compute sandbox and return a unique environment_id.
stream = client.interactions.create(
agent="antigravity-preview-05-2026",
input="Create a file called hello.txt with the content 'Hello from the sandbox!'",
environment={"type": "remote"},
stream=True,
background=True,
store=True,
)
env_id = None
for event in stream:
print(event)
# Extract environment_id from the completed event
if hasattr(event, 'interaction') and hasattr(event.interaction, 'environment_id'):
env_id = event.interaction.environment_id
print(f"\nEnvironment ID: {env_id}")Continue the Thread (Reusing the Environment)
Execute subsequent interaction requests by passing the active environment_id. The platform will load the pre-allocated sandbox session, preserving variables, local filesystem modifications, and conversational context.
if env_id:
stream = client.interactions.create(
agent="antigravity-preview-05-2026",
input="Read the file hello.txt and print its contents.",
environment=env_id,
stream=True,
background=True,
store=True,
)
print("Follow-up Response (same environment):")
print("=" * 60)
for event in stream:
print(event)
else:
print("No environment ID available. Run the previous cell first.")Override MCP Configurations at Interaction Time
You can dynamically override or add MCP server tools during an interaction without modifying the underlying agent configuration. This is useful for per-request tool customization.
Dynamically Inject and Override MCP Servers
At execution time, you can dynamically override the agent's control-plane MCP configuration or inject entirely new temporary tools by supplying a modified server dictionary within the interaction request.
stream = client.interactions.create(
agent=AGENT_ID,
input="Use the grep tool to search for 'fibonacci' in github.",
tools=[
{
"type": "mcp_server",
"url": "https://mcp.grep.app",
"name": "grep-search",
}
],
stream=True,
background=True,
store=True,
)
print("MCP Override Response:")
print("=" * 60)
for event in stream:
print(event)Cleanup
Delete the test agents we created. Agent configurations persist until explicitly deleted.
5. Clean Up Custom Agents
To release resources and keep your Google Cloud project clean, delete the custom agent configurations when they are no longer needed. Deleted agents are removed permanently from the control plane.
for agent_id_to_delete in [AGENT_ID, MCP_AGENT_ID]:
try:
response = client.agents.delete(id=agent_id_to_delete)
print(f"Deleted agent: {agent_id_to_delete}")
except Exception as e:
print(f"Failed to delete {agent_id_to_delete}: {e}")
# Verify cleanup
response = client.agents.list()
remaining = [a.id for a in response.agents] if response.agents else []
print(f"\nRemaining agents: {remaining if remaining else 'None'}")Quick Reference
Agents API
| Method | Code | Description |
|---|---|---|
| Create | client.agents.create(id=..., base_agent=..., ...) | Create a reusable custom agent |
| List | client.agents.list() | List all agents (supports pagination) |
| Get | client.agents.get(id="agent-id") | Retrieve a specific agent by ID |
| Delete | client.agents.delete(id="agent-id") | Delete an agent |
| Update | Not yet available in Python SDK | Use REST API |
Interactions API
| Method | Code | Description |
|---|---|---|
| Create (streaming) | client.interactions.create(agent=..., input=..., stream=True) | Stream interaction events |
| Create (blocking) | client.interactions.create(agent=..., input=...) | Get final result |
| Session reuse | environment="env_id_string" | Reuse sandbox state |
| MCP override | tools=[{"type": "mcp_server", ...}] | Dynamic tool override |
Key Parameters
| Parameter | Description |
|---|---|
agent | Base agent name or custom agent ID |
input | User prompt (string or structured content) |
environment | "remote", env_id string, or config dict |
stream | True for SSE streaming, False for blocking |
background | True to run in background |
store | True to persist for later retrieval |
tools | List of tool configs (MCP override, etc.) |
