Hook memungkinkan Anda menjalankan skrip kustom atau permintaan HTTP eksternal tepat sebelum atau setelah agen menjalankan kode atau mengubah file di dalam sandbox jarak jauhnya. Gunakan hook untuk memperluas loop agen dengan alur kerja latar belakang dan pembatasan otomatis, seperti:
- Menerapkan pengamanan keamanan dan akses sebelum perintah shell berisiko tinggi atau pembacaan file yang dibatasi dieksekusi.
- Mengotomatiskan transformasi pipeline data tepat setelah agen membuat atau mengubah file.
Mengalirkan telemetri audit perusahaan ke sistem pemantauan eksternal setelah eksekusi alat.
Python
import json
from google import genai
client = genai.Client()
hooks_config = {
"security-gate": {
"pre_tool_execution": [
{
"matcher": "code_execution",
"hooks": [
{
"type": "command",
"command": "python3 /.agents/hooks-scripts/gate.py",
"timeout": 10,
}
],
}
]
}
}
gate_script = """#!/usr/bin/env python3
import sys, json
data = json.load(sys.stdin)
cmd = str(data.get("tool_call", {}).get("args", {}))
if "rm -rf" in cmd:
print(json.dumps({"decision": "deny", "reason": "Destructive command blocked by security gate."}))
else:
print(json.dumps({"decision": "allow"}))
"""
interaction = client.interactions.create(
agent="antigravity-preview-05-2026",
input="Run `rm -rf /tmp/forbidden` using code_execution.",
tools=[{"type": "code_execution"}],
environment={
"type": "remote",
"sources": [
{
"type": "inline",
"target": ".agents/hooks.json",
"content": json.dumps(hooks_config, indent=2),
},
{
"type": "inline",
"target": ".agents/hooks-scripts/gate.py",
"content": gate_script,
},
],
},
)
print(interaction.output_text)
JavaScript
import { GoogleGenAI } from "@google/genai";
const client = new GoogleGenAI({});
const hooksConfig = {
"security-gate": {
pre_tool_execution: [
{
matcher: "code_execution",
hooks: [
{
type: "command",
command: "python3 /.agents/hooks-scripts/gate.py",
timeout: 10,
},
],
},
],
},
};
const gateScript = `#!/usr/bin/env python3
import sys, json
data = json.load(sys.stdin)
cmd = str(data.get("tool_call", {}).get("args", {}))
if "rm -rf" in cmd:
print(json.dumps({"decision": "deny", "reason": "Destructive command blocked by security gate."}))
else:
print(json.dumps({"decision": "allow"}))
`;
const interaction = await client.interactions.create({
agent: "antigravity-preview-05-2026",
input: "Run `rm -rf /tmp/forbidden` using code_execution.",
tools: [{ type: "code_execution" }],
environment: {
type: "remote",
sources: [
{
type: "inline",
target: ".agents/hooks.json",
content: JSON.stringify(hooksConfig, null, 2),
},
{
type: "inline",
target: ".agents/hooks-scripts/gate.py",
content: gateScript,
},
],
},
});
console.log(interaction.output_text);
Java
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.AgentOption;
import com.google.genai.gaos.models.interactions.CreateAgentInteraction;
import com.google.genai.gaos.models.interactions.Interaction;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
Client client = new Client();
CreateAgentInteraction params =
CreateAgentInteraction.builder()
.agent(AgentOption.of("antigravity-preview-05-2026"))
.input(InteractionsInput.of("Build a simple REST API server in Node.js."))
.build();
Interaction interaction =
client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();
System.out.println(interaction.outputText().orElse(""));
REST
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-d '{
"agent": "antigravity-preview-05-2026",
"input": [{"type": "text", "text": "Run `rm -rf /tmp/forbidden` using code_execution."}],
"tools": [{"type": "code_execution"}],
"environment": {
"type": "remote",
"sources": [
{
"type": "inline",
"target": ".agents/hooks.json",
"content": "{\"security-gate\": {\"pre_tool_execution\": [{\"matcher\": \"code_execution\", \"hooks\": [{\"type\": \"command\", \"command\": \"python3 /.agents/hooks-scripts/gate.py\", \"timeout\": 10}]}]}}"
},
{
"type": "inline",
"target": ".agents/hooks-scripts/gate.py",
"content": "#!/usr/bin/env python3\nimport sys, json\ndata = json.load(sys.stdin)\ncmd = str(data.get(\"tool_call\", {}).get(\"args\", {}))\nif \"rm -rf\" in cmd:\n print(json.dumps({\"decision\": \"deny\", \"reason\": \"Destructive command blocked by security gate.\"}))\nelse:\n print(json.dumps({\"decision\": \"allow\"}))\n"
}
]
}
}'
Peristiwa siklus proses yang didukung
Hook mendukung 2 peristiwa di dalam sandbox:
| Acara | Saat diaktifkan | Fungsinya |
|---|---|---|
pre_tool_execution |
Tepat sebelum alat berjalan | Dapat menyetujui (allow) atau memblokir (deny) alat sebelum dieksekusi. Saat diblokir, model akan melihat alasan penolakan Anda dan beradaptasi. |
post_tool_execution |
Tepat setelah alat selesai | Menjalankan tugas lanjutan seperti memformat kode, menjalankan pengujian unit, atau mencatat telemetri. Tidak dapat memblokir atau mengurungkan tindakan yang telah selesai. |
pre_tool_execution
Diaktifkan tepat sebelum alat dijalankan. Skrip Anda membaca detail panggilan alat dari stdin dan menampilkan JSON keputusannya (allow atau deny) ke stdout.
Payload input (stdin):
{
"tool_call": {
"name": "code_execution",
"args": {
"code": "rm -rf /tmp/forbidden",
"language": "bash"
}
},
"environment_id": "env_xyz789"
}
Respons output (stdout):
Untuk menyetujui panggilan alat:
{
"decision": "allow"
}
Untuk memblokir panggilan alat dan memberikan masukan ke model:
{
"decision": "deny",
"reason": "Destructive command blocked by security gate."
}
Jika hook menolak perintah, panggilan alat akan segera dilewati. Agen melihat hasil error yang berisi alasan penolakan Anda tepat di dalam gilirannya saat ini. Model kemudian dapat mengoreksi dirinya sendiri dengan memilih perintah alternatif atau menjelaskan pemblokiran kepada pengguna.
Jika skrip Anda menampilkan JSON yang tidak dikenal, teks biasa, atau apa pun selain {"decision": "deny"}, runtime akan memperlakukan respons sebagai persetujuan (allow).
post_tool_execution
Diaktifkan tepat setelah alat selesai. Skrip Anda membaca detail eksekusi dan status error dari stdin.
Payload input (stdin):
{
"tool_call": {
"name": "code_execution",
"args": {
"code": "python3 /workspace/app.py",
"language": "bash"
}
},
"environment_id": "env_xyz789"
}
Jika perintah shell mencetak error ke error standar (stderr) atau operasi sistem file gagal, kolom "error" yang berisi teks error akan disertakan dalam payload. Jika perintah berhasil tanpa error, kolom "error" akan dihilangkan sepenuhnya.
Respons output (stdout):
{}
Karena hook pasca-alat berjalan secara ketat untuk tugas latar belakang seperti pemformatan kode atau logging, runtime mengabaikan nilai keputusan apa pun yang ditampilkan di stdout.
Penemuan konfigurasi
Runtime otomatis menemukan definisi hook dari .agents/hooks.json atau /.agents/hooks.json di dalam lingkungan sandbox. Anda dapat menyediakan hooks.json bersama skrip kustom menggunakan sumber lingkungan yang didukung:
- Pemasangan repositori: Repositori Git yang berisi
.agents/hooks.jsonbersama denganAGENTS.md. - Cloud Storage (
gcs): Bucket GCS yang berisihooks.jsonyang disalin ke lingkungan. - Sumber inline: String JSON mentah dan konten skrip yang diteruskan di
environment.sourcessaat memanggilclient.interactions.create.
Skema hooks.json
File hooks.json mengelompokkan definisi peristiwa (pre_tool_execution atau post_tool_execution) dengan nama kustom. Anda dapat mengaktifkan atau menonaktifkan setiap grup secara terpisah:
{
"security-gate": {
"enabled": true,
"pre_tool_execution": [
{
"matcher": "code_execution",
"hooks": [
{
"type": "command",
"command": "python3 /.agents/hooks-scripts/gate.py",
"timeout": 10
}
]
}
]
},
"auto-format": {
"post_tool_execution": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "python3 /.agents/hooks-scripts/auto_lint.py",
"timeout": 15
}
]
}
]
}
}
Sintaksis dan aturan pencocokan
Setiap grup aturan di hooks.json menentukan kapan dan bagaimana handler diaktifkan menggunakan properti matcher dan hooks:
| Kolom | Jenis | Deskripsi |
|---|---|---|
enabled |
boolean |
Opsional. Tetapkan ke false untuk menonaktifkan grup (true secara default). |
matcher |
string |
Pencocokan pola ekspresi reguler untuk nama alat target di dalam penampung. |
hooks |
array |
Daftar terurut definisi pengendali (command atau http). Pengendali berjalan secara berurutan dalam urutan deklarasi. |
Cara kerja evaluasi regex
Saat agen memanggil alat di dalam sandbox, runtime akan mengevaluasi nama penampung alat terhadap pola matcher Anda menggunakan ekspresi reguler RE2 standar. Jika regex cocok dengan nama alat, semua handler dalam array hooks akan dieksekusi secara berurutan. Jika beberapa grup aturan cocok dengan alat yang sama, semua array handler yang sesuai akan berjalan.
Anda dapat menargetkan nama alat penampung bawaan: eksekusi kode (code_execution) atau operasi sistem file (read_file, write_file, list_files, dan delete_file).
Ekspresi pencocokan umum
"code_execution": Kecocokan string yang tepat untuk perintah shell dan eksekusi skrip."write_file": Kecocokan persis untuk pembuatan file sistem file dan penulisan disk."read_file|write_file": Pemisahan dengan tanda pipa mencocokkan beberapa nama alat tertentu dalam satu aturan.".*_file": Pencocokan karakter pengganti regex untuk alat apa pun yang diakhiri dengan_file(sepertiread_file,write_file, ataudelete_file). Ekspresi reguler RE2 standar memerlukan.*; glob shell sederhana seperti*_fileadalah sintaksis regex yang tidak valid dan tidak akan cocok.".*"atau"*"atau"": Pola umum yang mencegat setiap panggilan alat di dalam container.
Jenis penangan
Hook perintah
Hook perintah menjalankan perintah atau skrip shell di dalam sandbox. Skrip menerima JSON peristiwa di stdin dan menghasilkan JSON keputusannya di stdout.
| Kolom | Jenis | Deskripsi |
|---|---|---|
type |
string |
Harus berupa "command". |
command |
string |
Command line untuk dijalankan di dalam sandbox (misalnya, python3 /.agents/hooks-scripts/gate.py). |
timeout |
integer |
Waktu tunggu dalam detik. Default: 30. |
Hook HTTP
Hook HTTP mengirimkan JSON peristiwa sebagai permintaan POST ke URL HTTPS eksternal langsung dari dalam jaringan sandbox. Server target menampilkan keputusannya di isi respons HTTP menggunakan format JSON yang persis sama ({"decision": "allow"} atau {"decision": "deny", "reason": "..."}).
| Kolom | Jenis | Deskripsi |
|---|---|---|
type |
string |
Harus berupa "http". |
url |
string |
Endpoint HTTPS eksternal untuk mengirimkan payload peristiwa. |
headers |
object |
Pasangan nilai kunci opsional untuk header kustom yang tidak sensitif (seperti {"X-Event-Source": "agent-sandbox"}). Untuk kredensial autentikasi, gunakan proxy jaringan. |
timeout |
integer |
Waktu tunggu dalam detik. Default: 30. |
Proxy keluar dan transformasi token
Karena hook HTTP dieksekusi langsung dari dalam namespace jaringan sandbox, permintaan keluar melewati proxy keluar transparan. Arsitektur ini memberi Anda 2 keunggulan keamanan penting:
- Pengizinan jaringan: Endpoint target harus diizinkan secara eksplisit dalam
network.allowlistlingkungan Anda. Traffic loopback (127.0.0.1ataulocalhost) diblokir oleh proxy; selalu targetkan endpoint eksternal yang diizinkan. - Transformasi token: Anda tidak perlu menyimpan kunci API atau token pembawa rahasia di dalam
.agents/hooks.jsonatau memasangnya ke dalam penampung. Sebagai gantinya, konfigurasi aturan transformasi token di konfigurasi jaringan (network.allowlist.transform). Proxy keluar otomatis mencegat traffic hook HTTP keluar dan menyuntikkan header autentikasi asli Anda di jaringan sebelum keluar dari sandbox.
Cara runtime menangani keputusan dan kegagalan
- Penantian sinkron: Agen akan dijeda dan menunggu hingga hook Anda selesai sebelum melanjutkan.
- Memblokir eksekusi alat: Jika hook pra-alat menampilkan
{"decision": "deny", "reason": "<your reason>"}, runtime akan segera membatalkan panggilan alat. Model melihat alasan penolakan Anda dalam histori percakapannya dan beradaptasi dengan memilih alternatif yang aman atau menjelaskan pemblokiran kepada pengguna. - Menangani error skrip, error HTTP, dan waktu tunggu habis: Jika skrip perintah mengalami error (status keluar non-nol), hook HTTP menampilkan kode status non-2xx (seperti error server 4xx atau 5xx), atau operasi mengalami waktu tunggu habis atau menampilkan JSON yang tidak dikenali, runtime akan memperlakukannya sebagai persetujuan (
allow). Eksekusi alat berlanjut secara normal sehingga skrip yang rusak atau server telemetri yang tidak dapat dijangkau tidak akan pernah membuat aplikasi Anda mengalami kebuntuan.
Kasus penggunaan umum
Pemulihan multi-turn untuk privasi dan kepatuhan data
Jika hook memblokir akses ke resource terbatas—seperti direktori yang berisi Informasi Identitas Pribadi (PII) atau catatan keuangan rahasia—Anda dapat meneruskan previous_interaction_id pada panggilan berikutnya untuk melanjutkan giliran di lingkungan yang sama. Agen membaca penjelasan penolakan dan otomatis pulih dengan membuat kueri tabel publik yang disetujui.
Python
import json
from google import genai
client = genai.Client()
hooks_config = {
"privacy-gate": {
"pre_tool_execution": [
{
"matcher": "read_file",
"hooks": [
{
"type": "command",
"command": "python3 /.agents/hooks-scripts/check_privacy.py",
"timeout": 5,
}
],
}
]
}
}
check_privacy_script = """#!/usr/bin/env python3
import sys, json
data = json.load(sys.stdin)
path = str(data.get("tool_call", {}).get("args", {}).get("path", ""))
if "/private/" in path:
resp = {
"decision": "deny",
"reason": "Access to confidential `/private/` records is blocked by PII compliance policy. Query approved `/public/` summary tables instead."
}
else:
resp = {"decision": "allow"}
print(json.dumps(resp))
"""
# Step 1: Agent attempts to read confidential PII records and is intercepted
int_1 = client.interactions.create(
agent="antigravity-preview-05-2026",
input="Use your filesystem tool to read `/workspace/private/employees.json` and summarize the employee details.",
environment={
"type": "remote",
"sources": [
{
"type": "inline",
"target": ".agents/hooks.json",
"content": json.dumps(hooks_config, indent=2),
},
{
"type": "inline",
"target": ".agents/hooks-scripts/check_privacy.py",
"content": check_privacy_script,
},
{
"type": "inline",
"target": "workspace/private/employees.json",
"content": '{"employees": [{"id": 1, "salary": 150000, "ssn": "000-00-0000"}]}',
},
{
"type": "inline",
"target": "workspace/public/summary.json",
"content": '{"department": "Engineering", "team_size": 42, "status": "active"}',
},
],
},
)
print(int_1.output_text)
# Step 2: Continue in the same environment using previous_interaction_id; agent recovers with public tables
int_2 = client.interactions.create(
agent="antigravity-preview-05-2026",
input="Understood. Please read the approved `/workspace/public/summary.json` file instead and provide the summary.",
environment=int_1.environment_id,
previous_interaction_id=int_1.id,
)
print(int_2.output_text)
JavaScript
import { GoogleGenAI } from "@google/genai";
const client = new GoogleGenAI({});
const hooksConfig = {
"privacy-gate": {
pre_tool_execution: [
{
matcher: "read_file",
hooks: [
{
type: "command",
command: "python3 /.agents/hooks-scripts/check_privacy.py",
timeout: 5,
},
],
},
],
},
};
const checkPrivacyScript = `#!/usr/bin/env python3
import sys, json
data = json.load(sys.stdin)
path = str(data.get("tool_call", {}).get("args", {}).get("path", ""))
if "/private/" in path:
resp = {
"decision": "deny",
"reason": "Access to confidential \`/private/\` records is blocked by PII compliance policy. Query approved \`/public/\` summary tables instead."
}
else:
resp = {"decision": "allow"}
print(json.dumps(resp))
`;
const int1 = await client.interactions.create({
agent: "antigravity-preview-05-2026",
input: "Use your filesystem tool to read `/workspace/private/employees.json` and summarize the employee details.",
environment: {
type: "remote",
sources: [
{
type: "inline",
"target": ".agents/hooks.json",
content: JSON.stringify(hooksConfig, null, 2),
},
{
type: "inline",
"target": ".agents/hooks-scripts/check_privacy.py",
content: checkPrivacyScript,
},
{
type: "inline",
"target": "workspace/private/employees.json",
content: '{"employees": [{"id": 1, "salary": 150000, "ssn": "000-00-0000"}]}',
},
{
type: "inline",
"target": "workspace/public/summary.json",
content: '{"department": "Engineering", "team_size": 42, "status": "active"}',
},
],
},
});
console.log(int1.output_text);
const int2 = await client.interactions.create({
agent: "antigravity-preview-05-2026",
input: "Understood. Please read the approved `/workspace/public/summary.json` file instead and provide the summary.",
environment: int1.environment_id,
previous_interaction_id: int1.id,
});
console.log(int2.output_text);
Java
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.AgentOption;
import com.google.genai.gaos.models.interactions.CreateAgentInteraction;
import com.google.genai.gaos.models.interactions.Interaction;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
Client client = new Client();
CreateAgentInteraction params =
CreateAgentInteraction.builder()
.agent(AgentOption.of("antigravity-preview-05-2026"))
.input(InteractionsInput.of("Build a simple REST API server in Node.js."))
.build();
Interaction interaction =
client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();
System.out.println(interaction.outputText().orElse(""));
REST
# Step 1: Attempt to access restricted PII directory (blocked by hook)
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-d '{
"agent": "antigravity-preview-05-2026",
"input": [{"type": "text", "text": "Use your filesystem tool to read /workspace/private/employees.json and summarize the employee details."}],
"environment": {
"type": "remote",
"sources": [
{
"type": "inline",
"target": ".agents/hooks.json",
"content": "{\"privacy-gate\": {\"pre_tool_execution\": [{\"matcher\": \"read_file\", \"hooks\": [{\"type\": \"command\", \"command\": \"python3 /.agents/hooks-scripts/check_privacy.py\", \"timeout\": 5}]}]}}"
},
{
"type": "inline",
"target": ".agents/hooks-scripts/check_privacy.py",
"content": "#!/usr/bin/env python3\nimport sys, json\ndata = json.load(sys.stdin)\npath = str(data.get(\"tool_call\", {}).get(\"args\", {}).get(\"path\", \"\"))\nif \"/private/\" in path:\n resp = {\"decision\": \"deny\", \"reason\": \"Access to confidential `/private/` records is blocked by PII compliance policy. Query approved `/public/` summary tables instead.\"}\nelse:\n resp = {\"decision\": \"allow\"}\nprint(json.dumps(resp))\n"
},
{
"type": "inline",
"target": "workspace/private/employees.json",
"content": "{\"employees\": [{\"id\": 1, \"salary\": 150000, \"ssn\": \"000-00-0000\"}]}"
},
{
"type": "inline",
"target": "workspace/public/summary.json",
"content": "{\"department\": \"Engineering\", \"team_size\": 42, \"status\": \"active\"}"
}
]
}
}'
# Step 2: Continue in the same environment using $ENV_ID and $INTERACTION_ID from the previous response
# curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
# -H "Content-Type: application/json" \
# -H "x-goog-api-key: $GEMINI_API_KEY" \
# -d '{
# "agent": "antigravity-preview-05-2026",
# "input": [{"type": "text", "text": "Understood. Please read the approved /workspace/public/summary.json file instead and provide the summary."}],
# "environment": "'"$ENV_ID"'",
# "previous_interaction_id": "'"$INTERACTION_ID"'"
# }'
Telemetri dan logging audit eksternal
Kirim peristiwa audit real-time dari dalam kotak pasir ke server pemantauan eksternal setiap kali file dibaca atau diubah.
- Mencocokkan beberapa alat: Karena matcher menggunakan regex standar, Anda dapat menggabungkan beberapa alat dalam satu aturan menggunakan garis vertikal (
read_file|write_file) atau karakter pengganti (.*_file). Menjaga kerahasiaan konfigurasi Anda: Tentukan token autentikasi dalam konfigurasi jaringan lingkungan Anda (
network.allowlist.transform). Proxy keluar otomatis menyuntikkan token pembawa asli Anda pada permintaan keluar.
Python
import json
from google import genai
client = genai.Client()
# Define hook without secrets; the egress proxy injects headers dynamically
hooks_config = {
"audit-logging": {
"post_tool_execution": [
{
"matcher": "read_file|write_file",
"hooks": [
{
"type": "http",
"url": "https://telemetry.example.com/api/v1/agent-events",
"timeout": 10,
}
],
}
]
}
}
interaction = client.interactions.create(
agent="antigravity-preview-05-2026",
input="Use your filesystem tool to create `/workspace/audit.log` containing 'event 1', then immediately read it back using your filesystem read tool.",
environment={
"type": "remote",
"sources": [
{
"type": "inline",
"target": ".agents/hooks.json",
"content": json.dumps(hooks_config, indent=2),
}
],
"network": {
"allowlist": [
{
"domain": "telemetry.example.com",
"transform": {
"Authorization": "Bearer telemetry_secret_token_123",
},
},
{"domain": "*"},
]
},
},
)
print(interaction.output_text)
JavaScript
import { GoogleGenAI } from "@google/genai";
const client = new GoogleGenAI({});
// Define hook without secrets; the egress proxy injects headers dynamically
const hooksConfig = {
"audit-logging": {
post_tool_execution: [
{
matcher: "read_file|write_file",
hooks: [
{
type: "http",
url: "https://telemetry.example.com/api/v1/agent-events",
timeout: 10,
},
],
},
],
},
};
const interaction = await client.interactions.create({
agent: "antigravity-preview-05-2026",
input: "Use your filesystem tool to create `/workspace/audit.log` containing 'event 1', then immediately read it back using your filesystem read tool.",
environment: {
type: "remote",
sources: [
{
type: "inline",
target: ".agents/hooks.json",
content: JSON.stringify(hooksConfig, null, 2),
},
],
network: {
allowlist: [
{
domain: "telemetry.example.com",
transform: {
Authorization: "Bearer telemetry_secret_token_123",
},
},
{ domain: "*" },
],
},
},
});
console.log(interaction.output_text);
Java
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.AgentOption;
import com.google.genai.gaos.models.interactions.CreateAgentInteraction;
import com.google.genai.gaos.models.interactions.Interaction;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
Client client = new Client();
CreateAgentInteraction params =
CreateAgentInteraction.builder()
.agent(AgentOption.of("antigravity-preview-05-2026"))
.input(InteractionsInput.of("Build a simple REST API server in Node.js."))
.build();
Interaction interaction =
client.interactions.create(CreateInteractionRequestBody.of(params)).interaction().get();
System.out.println(interaction.outputText().orElse(""));
REST
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-d '{
"agent": "antigravity-preview-05-2026",
"input": [{"type": "text", "text": "Use your filesystem tool to create /workspace/audit.log containing event 1, then immediately read it back using your filesystem read tool."}],
"environment": {
"type": "remote",
"sources": [
{
"type": "inline",
"target": ".agents/hooks.json",
"content": "{\"audit-logging\": {\"post_tool_execution\": [{\"matcher\": \"read_file|write_file\", \"hooks\": [{\"type\": \"http\", \"url\": \"https://telemetry.example.com/api/v1/agent-events\", \"timeout\": 10}]}]}}"
}
],
"network": {
"allowlist": [
{
"domain": "telemetry.example.com",
"transform": {
"Authorization": "Bearer telemetry_secret_token_123"
}
},
{"domain": "*"}
]
}
}
}'
Batasan
- Cakupan alat sandbox: Hook mencegat alat bawaan di dalam sandbox: eksekusi kode (
code_execution) dan operasi sistem file (read_file,write_file,list_files, dandelete_file). Hook tidak diaktifkan untuk panggilan fungsi kustom (function) atau alat Model Context Protocol (mcp_server) eksternal yang ditangani di luar container. - Daftar yang diizinkan jaringan: Hook HTTP berjalan di dalam jaringan penampung. Anda harus mengizinkan URL target secara eksplisit di
network.allowlistlingkungan Anda. Alamat loopback (localhost,127.0.0.1) diblokir oleh proxy. - Persetujuan otomatis saat terjadi error: Jika skrip hook mengalami error (status keluar bukan nol), waktu habis, atau gagal, runtime akan mencatat kegagalan dan mengizinkan panggilan alat untuk dilanjutkan. Hal ini memastikan skrip linter yang rusak atau proses yang terhenti tidak pernah membuat aplikasi Anda mengalami kebuntuan.
- Perlindungan konfigurasi sandbox: Karena hook dijalankan di dalam sandbox penampung, agen dengan izin eksekusi kode shell atau alat penulisan sistem file dapat mengubah
.agents/hooks.jsonlokal atau skrip dalam ruang kerja yang dapat ditulis. Gunakan hook penampung sebagai panduan kebijakan otomatis dan pengamanan operasional; jika diperlukan ketahanan terhadap gangguan yang ketat terhadap eksekusi model yang tidak tepercaya, pasang sumber konfigurasi dari repositori hanya baca.
Langkah berikutnya
- Pelajari cara mengonfigurasi sandbox dan lingkungan jarak jauh yang persisten.
- Jelajahi kemampuan dan alat bawaan agen Antigravity.
- Tinjau Ringkasan Interactions API untuk sesi multi-turn dan streaming.