Kancalar

Kancalar, aracı kod yürütmeden veya uzak korumalı alanındaki dosyaları değiştirmeden hemen önce ya da sonra özel komut dosyaları veya harici HTTP istekleri çalıştırmanıza olanak tanır. Aşağıdakiler gibi otomatik koruma rayları ve arka plan iş akışlarıyla aracı döngüsünü genişletmek için kancaları kullanın:

  • Yüksek riskli kabuk komutları veya kısıtlanmış dosya okuma işlemleri yürütülmeden önce güvenlik ve erişim koruma duvarlarını zorunlu kılma
  • Bir aracı, dosyaları oluşturduktan veya değiştirdikten hemen sonra veri ardışık düzeni dönüşümlerini otomatikleştirme
  • Araç yürütüldükten sonra kurumsal denetim telemetrisini harici izleme sistemlerine aktarma.

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);

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"
              }
          ]
      }
  }'

Desteklenen yaşam döngüsü etkinlikleri

Kancalar, korumalı alanda 2 etkinliği destekler:

Etkinlik Tetiklenme zamanı Ne işe yarar?
pre_tool_execution Bir araç çalıştırılmadan hemen önce Araç yürütülmeden önce onaylayabilir (allow) veya engelleyebilir (deny). Engellendiğinde model, ret nedeninizi görür ve buna göre uyum sağlar.
post_tool_execution Bir araç tamamlandıktan hemen sonra Kodu biçimlendirme, birim testleri çalıştırma veya telemetri kaydetme gibi takip görevlerini yürütür. Tamamlanan işlemler engellenemez veya geri alınamaz.

pre_tool_execution

Bir araç yürütülmeden hemen önce tetiklenir. Komut dosyanız, araç çağrısı ayrıntılarını stdin konumundan okur ve karar JSON'ını (allow veya deny) stdout konumuna verir.

Giriş yükü (stdin):

{
  "tool_call": {
    "name": "code_execution",
    "args": {
      "code": "rm -rf /tmp/forbidden",
      "language": "bash"
    }
  },
  "environment_id": "env_xyz789"
}

Çıkış yanıtı (stdout):

Araç çağrısını onaylamak için:

{
  "decision": "allow"
}

Araç çağrısını engellemek ve modele geri bildirim göndermek için:

{
  "decision": "deny",
  "reason": "Destructive command blocked by security gate."
}

Bir kanca komutu reddettiğinde araç çağrısı hemen atlanır. Ajan, mevcut dönüşünde reddetme nedeninizi içeren bir hata sonucu görür. Model, alternatif bir komut seçerek veya engellemeyi kullanıcıya açıklayarak kendini düzeltebilir.

Komut dosyanız tanınmayan JSON, düz metin veya {"decision": "deny"} dışında bir şey çıkışı veriyorsa çalışma zamanı, yanıtı onay (allow) olarak değerlendirir.

post_tool_execution

Bir araç tamamlandıktan hemen sonra tetiklenir. Komut dosyanız, yürütme ayrıntılarını ve hata durumlarını stdin kaynağından okur.

Giriş yükü (stdin):

{
  "tool_call": {
    "name": "code_execution",
    "args": {
      "code": "python3 /workspace/app.py",
      "language": "bash"
    }
  },
  "environment_id": "env_xyz789"
}

Bir kabuk komutu, hataları standart hataya (stderr) yazdırırsa veya bir dosya sistemi işlemi başarısız olursa yükte hata metnini içeren bir "error" alanı yer alır. Komut hatasız olarak başarıyla tamamlandığında "error" alanı tamamen atlanır.

Çıkış yanıtı (stdout):

{}

Araç sonrası kancalar yalnızca kod biçimlendirme veya günlük kaydı gibi arka plan görevleri için çalıştığından çalışma zamanı, stdout üzerinde döndürülen tüm karar değerlerini yoksayar.

Yapılandırma keşfi

Çalışma zamanı, kancaların tanımlarını korumalı alan ortamındaki .agents/hooks.json veya /.agents/hooks.json'den otomatik olarak keşfeder. Desteklenen herhangi bir ortam kaynağını kullanarak özel komut dosyalarınızla birlikte hooks.json sağlayabilirsiniz:

  • Depo bağlama: AGENTS.md ile birlikte .agents/hooks.json içeren bir Git deposu.
  • Cloud Storage (gcs): Ortama kopyalanan hooks.json içeren bir GCS paketi.
  • Satır içi kaynaklar: client.interactions.create çağrılırken environment.sources içinde iletilen ham JSON dizesi ve komut dosyası içerikleri.

hooks.json şeması

hooks.json dosyası, etkinlik tanımlarını (pre_tool_execution veya post_tool_execution) özel adlar altında gruplandırır. Her grubu bağımsız olarak etkinleştirebilir veya devre dışı bırakabilirsiniz:

{
  "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
          }
        ]
      }
    ]
  }
}

Eşleştirici söz dizimi ve kuralları

hooks.json içindeki her kural grubu, matcher ve hooks özellikleri kullanılarak işleyicilerin ne zaman ve nasıl tetikleneceğini tanımlar:

Alan Tür Açıklama
enabled boolean İsteğe bağlı. Grubu devre dışı bırakmak için false olarak ayarlayın (varsayılan olarak true).
matcher string Kapsayıcının içindeki hedef araç adlarıyla eşleşen normal ifade kalıbı.
hooks array İşleyici tanımlarının sıralı listesi (command veya http). İşleyiciler, bildirim sırasına göre sırayla çalışır.

Normal ifade değerlendirmesinin işleyiş şekli

Aracı, sanal ortamda bir aracı çağırdığında çalışma zamanı, standart RE2 normal ifadelerini kullanarak aracın kapsayıcı adını matcher kalıbınıza göre değerlendirir. Normal ifade, araç adıyla eşleşirse hooks dizisindeki tüm işleyiciler sırayla yürütülür. Birden fazla kural grubu aynı araçla eşleşirse karşılık gelen tüm işleyici dizileri çalıştırılır.

Yerleşik kapsayıcı araç adlarından herhangi birini (kod yürütme [code_execution] veya dosya sistemi işlemleri [read_file, write_file, list_files ve delete_file]) hedefleyebilirsiniz.

Sık kullanılan eşleştirici ifadeler

  • "code_execution": Kabuk komutları ve komut dosyası yürütmeleri için tam dize eşleşmesi.
  • "write_file": Dosya sistemi dosya oluşturma ve disk yazma işlemleri için tam eşleşme.
  • "read_file|write_file": Dikey çizgiyle ayırma, tek bir kuralda birden fazla belirli araç adıyla eşleşiyor.
  • ".*_file": _file ile biten tüm araçlarla (ör. read_file, write_file veya delete_file) eşleşen normal ifade joker karakteri. Standart RE2 normal ifadeleri .* gerektirir. *_file gibi basit kabuk globları geçersiz normal ifade söz dizimidir ve eşleşmez.
  • ".*" veya "*" veya "": Kapsayıcıdaki her araç çağrısını yakalayan genel bir kalıptır.

İşleyici türleri

Komut kancaları

Komut kancaları, sanal alan içinde bir kabuk komutu veya komut dosyası yürütür. Komut dosyası, stdin üzerinde etkinlik JSON'unu alır ve stdout üzerinde karar JSON'unu verir.

Alan Tür Açıklama
type string "command" olmalıdır.
command string Korumalı alanda çalıştırılacak komut satırı (ör. python3 /.agents/hooks-scripts/gate.py).
timeout integer Saniye cinsinden zaman aşımı. Varsayılan: 30.

HTTP kancaları

HTTP kancaları, etkinlik JSON'unu doğrudan sanal alan ağının içinden harici bir HTTPS URL'sine POST isteği olarak gönderir. Hedef sunucu, kararını HTTP yanıt gövdesinde tam olarak aynı JSON biçimini ({"decision": "allow"} veya {"decision": "deny", "reason": "..."}) kullanarak döndürür.

Alan Tür Açıklama
type string "http" olmalıdır.
url string Etkinlik yükünün POST edileceği harici HTTPS uç noktası.
headers object Hassas olmayan özel başlıklar (ör. {"X-Event-Source": "agent-sandbox"}) için isteğe bağlı anahtar/değer çiftleri. Kimlik doğrulama kimlik bilgileri için bunun yerine ağ proxy'sini kullanın.
timeout integer Saniye cinsinden zaman aşımı. Varsayılan: 30.

Çıkış proxy'si ve jeton dönüşümü

HTTP kancaları doğrudan sandbox ağ ad alanı içinden yürütüldüğünden giden istekler, şeffaf çıkış proxy'si üzerinden geçer. Bu mimari, size 2 kritik güvenlik avantajı sağlar:

  • Ağ izin verilenler listesi: Hedef uç noktaların, ortamınızın network.allowlist bölümünde açıkça izin verilmiş olması gerekir. Geri döngü trafiği (127.0.0.1 veya localhost) proxy tarafından engellenir. Her zaman izin verilenler listesindeki harici uç noktaları hedefleyin.
  • Jeton dönüştürme: API anahtarlarını veya gizli taşıyıcı jetonlarını .agents/hooks.json içinde saklamanız ya da kapsayıcıya bağlamanız gerekmez. Bunun yerine, ağ yapılandırmanızda (network.allowlist.transform) jeton dönüştürme kurallarını yapılandırın. Çıkış proxy'si, giden HTTP kanca trafiğini otomatik olarak yakalar ve sanal ortamdan ayrılmadan önce gerçek kimlik doğrulama üstbilgilerinizi kabloya yerleştirir.

Çalışma zamanı, kararları ve hataları nasıl ele alır?

  • Senkronize bekleme: Ajan, devam etmeden önce duraklatır ve kancalarınızın tamamlanmasını bekler.
  • Araç yürütmeyi engelleme: Araç öncesi kancanız {"decision": "deny", "reason": "<your reason>"} değerini döndürürse çalışma zamanı, araç çağrısını hemen iptal eder. Model, reddetme nedeninizi sohbet geçmişinde görür ve güvenli bir alternatif seçerek veya engellemeyi kullanıcıya açıklayarak uyum sağlar.
  • Komut dosyası çökmelerini, HTTP hatalarını ve zaman aşımlarını işleme: Bir komut dosyası çökerse (sıfır olmayan çıkış durumu), bir HTTP kancası 2xx olmayan bir durum kodu (ör. 4xx veya 5xx sunucu hatası) döndürürse ya da bir işlem zaman aşımına uğrarsa veya tanınmayan JSON döndürürse çalışma zamanı bunu onay olarak değerlendirir (allow). Araç yürütme normal şekilde devam eder. Böylece bozuk bir komut dosyası veya ulaşılamayan bir telemetri sunucusu uygulamanızda hiçbir zaman kilitlenmeye neden olmaz.

Yaygın kullanım alanları

Veri gizliliği ve uygunluk için çok turlu kurtarma

Bir kanca, kimliği tanımlayabilecek bilgiler (PII) veya gizli finansal kayıtlar içeren dizinler gibi kısıtlanmış kaynaklara erişimi engellediğinde, aynı ortamda dönüşe devam etmek için sonraki çağrıda previous_interaction_id değerini iletebilirsiniz. Aracı, ret açıklamasını okur ve bunun yerine onaylanmış herkese açık tabloları sorgulayarak otomatik olarak kurtarır.

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);

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"'"
#   }'

Harici denetleme günlüğü ve telemetri

Dosyalar okunduğunda veya değiştirildiğinde korumalı alanın içinden harici bir izleme sunucusuna gerçek zamanlı denetim etkinlikleri gönderin.

  • Birden fazla aracı eşleştirme: Eşleştiriciler standart normal ifade kullandığından, dikey çizgi (read_file|write_file) veya joker karakterler (.*_file) kullanarak birden fazla aracı tek bir kuralda birleştirebilirsiniz.
  • Yapılandırmanızda sırları saklamayın: Ortamınızın ağ yapılandırmasında (network.allowlist.transform) kimlik doğrulama jetonlarını tanımlayın. Çıkış proxy'si, giden isteklerde gerçek taşıyıcı jetonlarınızı otomatik olarak ekler.

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);

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": "*"}
              ]
          }
      }
  }'

Sınırlamalar

  • Korumalı alan aracı kapsamı: Kancalar, korumalı alan içindeki yerleşik araçları (kod yürütme code_execution ve dosya sistemi işlemleri read_file, write_file, list_files ve delete_file) yakalar. Kancalar, özel işlev çağrıları (function) veya kapsayıcının dışında işlenen harici Model Bağlam Protokolü (mcp_server) araçları için tetiklenmez.
  • Ağ izin verilenler listeleri: HTTP kancaları, kapsayıcı ağında çalışır. Ortamınızın network.allowlist bölümünde hedef URL'lere açıkça izin vermeniz gerekir. Geri döngü adresleri (localhost, 127.0.0.1) proxy tarafından engellenir.
  • Hatalarda otomatik onay: Bir kanca komut dosyası çökerse (sıfır olmayan çıkış durumu), zaman aşımına uğrarsa veya başarısız olursa çalışma zamanı hatayı günlüğe kaydeder ve araç çağrısının devam etmesine izin verir. Bu sayede, bozuk linter komut dosyaları veya askıda kalan işlemler uygulamalarınızın kilitlenmesine neden olmaz.
  • Korumalı alan yapılandırma koruması: Kancalar kapsayıcı korumalı alanında yürütüldüğünden, dosya sistemi yazma araçları veya kabuk kodu yürütme izinleri olan aracılar, yerel .agents/hooks.json veya yazılabilir çalışma alanlarındaki komut dosyalarını değiştirebilir. Kapsayıcı kancalarını otomatik politika kılavuzu ve operasyonel koruma rayları olarak kullanın. Güvenilmeyen model yürütmelerine karşı sıkı kurcalamaya karşı direnç gerekiyorsa yapılandırma kaynaklarını salt okunur depolardan monte edin.

Sırada ne var?