Grepa, Grepa

Grepat ju lejojnë të ekzekutoni skripte të personalizuara ose kërkesa HTTP të jashtme menjëherë para ose pasi agjenti të ekzekutojë kodin ose të modifikojë skedarët brenda sandbox-it të tij të largët. Përdorni grepat për të zgjeruar ciklin e agjentit me parmakë mbrojtës të automatizuar dhe rrjedha pune në sfond, të tilla si:

  • Zbatimi i kangjellave të sigurisë dhe aksesit përpara se të ekzekutohen komandat e shell me rrezik të lartë ose leximet e kufizuara të skedarëve.
  • Automatizimi i transformimeve të tubacionit të të dhënave menjëherë pasi një agjent krijon ose modifikon skedarë.
  • Transmetimi i telemetrisë së auditimit të ndërmarrjes në sisteme monitorimi të jashtme pas ekzekutimit të mjetit.

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

PUSHTIM

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

Ngjarjet e mbështetura të ciklit jetësor

Grepat mbështesin 2 ngjarje brenda sandbox-it:

Ngjarje Kur ndizet Çfarë bën
pre_tool_execution Pak para se të funksionojë një mjet Mund ta miratojë ( allow ) ose ta bllokojë ( deny ) mjetin përpara se të ekzekutohet. Kur bllokohet, modeli e sheh arsyen e refuzimit tuaj dhe përshtatet.
post_tool_execution Menjëherë pasi mbaron një mjet Ekzekuton detyra ndjekëse si formatimi i kodit, ekzekutimi i testeve të njësisë ose regjistrimi i telemetrisë. Nuk mund të bllokojë ose zhbëjë veprimet e përfunduara.

pre_tool_execution

Aktivizohet menjëherë para se të ekzekutohet një mjet. Skripti juaj lexon detajet e thirrjes së mjetit nga stdin dhe nxjerr vendimin e tij në formatin JSON ( allow ose deny ) te stdout .

Ngarkesa hyrëse ( stdin ):

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

Përgjigja e daljes ( stdout ):

Për të miratuar thirrjen e mjetit:

{
  "decision": "allow"
}

Për të bllokuar thirrjen e mjetit dhe për të kthyer reagime te modeli:

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

Kur një grep mohon një komandë, thirrja e mjetit anashkalohet menjëherë. Agjenti sheh një rezultat gabimi që përmban arsyen e refuzimit tuaj brenda radhës së tij aktuale. Modeli më pas mund të vetëkorrigjohet duke zgjedhur një komandë alternative ose duke ia shpjeguar bllokun përdoruesit.

Nëse skripti juaj nxjerr JSON të panjohur, tekst të thjeshtë ose diçka tjetër përveç {"decision": "deny"} , koha e ekzekutimit e trajton përgjigjen si një miratim ( allow ).

post_tool_execution

Aktivizohet menjëherë pasi një mjet përfundon. Skripti juaj lexon detajet e ekzekutimit dhe çdo status gabimi nga stdin .

Ngarkesa hyrëse ( stdin ):

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

Nëse një komandë shell printon gabime në standard error ( stderr ) ose një operacion i sistemit të skedarëve dështon, një fushë "error" që përmban tekstin e gabimit përfshihet në ngarkesë. Kur komanda ka sukses pa gabime, fusha "error" lihet plotësisht jashtë.

Përgjigja e daljes ( stdout ):

{}

Meqenëse grepat post-tool funksionojnë vetëm për detyra në sfond, siç janë formatimi i kodit ose regjistrimi, koha e ekzekutimit injoron çdo vlerë vendimi të kthyer në stdout .

Zbulimi i konfigurimit

Runtime zbulon automatikisht përkufizimet e hook-eve nga .agents/hooks.json ose /.agents/hooks.json brenda mjedisit sandbox. Ju mund të ofroni hooks.json së bashku me skriptet tuaja të personalizuara duke përdorur çdo burim të mjedisit të mbështetur:

  • Montimi i depos : Një depo Git që përmban .agents/hooks.json së bashku me AGENTS.md .
  • Ruajtja në renë kompjuterike ( gcs ) : Një depo GCS që përmban hooks.json e kopjuar në mjedis.
  • Burime të brendshme : Përmbajtja e vargut dhe skriptit të papërpunuar JSON të kaluara në environment.sources gjatë thirrjes së client.interactions.create .

skema hooks.json

Një skedar hooks.json grupon përkufizimet e ngjarjeve ( pre_tool_execution ose post_tool_execution ) nën emra të personalizuar. Ju mund ta aktivizoni ose çaktivizoni secilin grup në mënyrë të pavarur:

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

Sintaksa dhe rregullat e përputhjes

Çdo grup rregullash në hooks.json përcakton se kur dhe si aktivizohen trajtuesit duke përdorur vetitë matcher dhe hooks :

Fushë Lloji Përshkrimi
enabled boolean Opsionale. Vendoseni në false për të çaktivizuar grupin ( true si parazgjedhje).
matcher string Modeli i shprehjeve të rregullta përputhet me emrat e mjeteve të synuara brenda kontejnerit.
hooks array Listë e renditur e përkufizimeve të trajtuesve ( command ose http ). Trajtuesit ekzekutohen në mënyrë sekuenciale sipas renditjes së deklarimeve.

Si funksionon vlerësimi i regex-it

Kur agjenti thërret një mjet brenda sandbox-it, koha e ekzekutimit vlerëson emrin e kontejnerit të mjetit kundrejt modelit tuaj matcher duke përdorur shprehje të rregullta standarde RE2. Nëse regex përputhet me emrin e mjetit, të gjithë trajtuesit në vargun hooks ekzekutohen me radhë. Nëse grupe të shumta rregullash përputhen me të njëjtin mjet, të gjitha vargjet përkatëse të trajtuesve ekzekutohen.

Mund të caktoni çdo emër mjeti të integruar kontejneri: ekzekutimin e kodit ( code_execution ) ose operacionet e sistemit të skedarëve ( read_file , write_file , list_files dhe delete_file ).

Shprehje të zakonshme përputhjeje

  • "code_execution" : Përputhje e saktë e vargut për komandat shell dhe ekzekutimet e skripteve.
  • "write_file" : Përputhje e saktë për krijimin e skedarëve të sistemit të skedarëve dhe shkrimet në disk.
  • "read_file|write_file" : Ndarja e tubave përputhet me emra të shumtë specifikë mjetesh në një rregull të vetëm.
  • ".*_file" : Karakteristika e egër regex përputhet me çdo mjet që mbaron me _file (si p.sh. read_file , write_file ose delete_file ). Shprehjet e rregullta standarde RE2 kërkojnë .* ; glob-et e thjeshta të shell-it si *_file janë sintaksë e pavlefshme regex dhe nuk do të përputhen.
  • ".*" ose "*" ose "" : Model gjithëpërfshirës që kap çdo thirrje të vetme të mjetit brenda kontejnerit.

Llojet e trajtuesve

Grepa komandash

Hook-et e komandave ekzekutojnë një komandë shell ose skript brenda sandbox-it. Skripti merr ngjarjen JSON në stdin dhe nxjerr vendimin e tij JSON në stdout .

Fushë Lloji Përshkrimi
type string Duhet të jetë "command" .
command string Rreshti i komandës për t'u ekzekutuar brenda sandbox-it (për shembull, python3 /.agents/hooks-scripts/gate.py ).
timeout integer Kohëzgjatja në sekonda. Parazgjedhja: 30 .

Grepa HTTP

Grepat HTTP dërgojnë ngjarjen JSON si një kërkesë POST në një URL HTTPS të jashtme direkt nga brenda rrjetit sandbox. Serveri i synuar kthen vendimin e tij në trupin e përgjigjes HTTP duke përdorur saktësisht të njëjtin format JSON ( {"decision": "allow"} ose {"decision": "deny", "reason": "..."} ).

Fushë Lloji Përshkrimi
type string Duhet të jetë "http" .
url string Pikë fundore HTTPS e jashtme për të POST-uar ngarkesën e ngjarjes.
headers object Çifte opsionale çelës-vlerë për tituj të personalizuar jo të ndjeshëm (si p.sh. {"X-Event-Source": "agent-sandbox"} ). Për kredencialet e vërtetimit, përdorni në vend të tyre proxy-n e rrjetit.
timeout integer Kohëzgjatja në sekonda. Parazgjedhja: 30 .

Transformimi i proxy-t dhe token-it të daljes

Meqenëse grepat HTTP ekzekutohen direkt nga brenda hapësirës së emrave të rrjetit sandbox, kërkesat dalëse kalojnë përmes proxy-t transparent të daljes. Kjo arkitekturë ju jep 2 avantazhe kritike sigurie:

  • Vendosja në listën e lejuar të rrjetit: Pikat fundore të synuara duhet të lejohen në mënyrë të qartë në network.allowlist të mjedisit tuaj. Trafiku i rikthimit ( 127.0.0.1 ose localhost ) bllokohet nga proxy; gjithmonë synoni pikat fundore të jashtme të listës së lejuar.
  • Transformimi i tokenëve: Nuk keni nevojë të ruani çelësa API ose tokena bartës sekretë brenda .agents/hooks.json ose t'i montoni ato në kontejner. Në vend të kësaj, konfiguroni rregullat e transformimit të tokenëve në konfigurimin e rrjetit tuaj ( network.allowlist.transform ). Proxy-ja e daljes ndërpret automatikisht trafikun dalës të HTTP hook dhe injekton kokat tuaja të vërtetimit të vërtetë në tel përpara se të largohet nga sandbox-i.

Si i trajton koha e ekzekutimit vendimet dhe dështimet

  • Pritja sinkrone: Agjenti ndalet dhe pret që goditjet tuaja të përfundojnë përpara se të vazhdojë.
  • Bllokimi i ekzekutimit të mjetit: Nëse goditja juaj paraprake e mjetit kthen {"decision": "deny", "reason": "<your reason>"} , koha e ekzekutimit anulon menjëherë thirrjen e mjetit. Modeli e sheh arsyen e refuzimit tuaj në historikun e bisedës së tij dhe përshtatet duke zgjedhur një alternativë të sigurt ose duke ia shpjeguar bllokimin përdoruesit.
  • Trajtimi i bllokimeve të skriptit, gabimeve HTTP dhe skadimeve të kohës: Nëse një skript komande bllokohet (status daljeje jo-zero), një grep HTTP kthen një kod statusi jo-2xx (siç është një gabim serveri 4xx ose 5xx), ose një operacion skadon ose kthen JSON të panjohur, koha e ekzekutimit e trajton atë si një miratim ( allow ). Ekzekutimi i mjetit vazhdon normalisht, kështu që një skript i prishur ose një server telemetrie i paarritshëm nuk e bllokon kurrë aplikacionin tuaj.

Rastet e përdorimit të zakonshëm

Rimëkëmbje me shumë kthesa për privatësinë dhe pajtueshmërinë e të dhënave

Kur një grep bllokon aksesin në burime të kufizuara - siç janë drejtoritë që përmbajnë Informacion Personal të Identifikueshëm (PII) ose të dhëna financiare konfidenciale - ju mund të kaloni previous_interaction_id në thirrjen tjetër për të vazhduar kthesën në të njëjtin mjedis. Agjenti lexon shpjegimin e refuzimit dhe rikuperohet automatikisht duke pyetur tabelat publike të miratuara në vend të kësaj.

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

PUSHTIM

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

Regjistrimi i auditimit të jashtëm dhe telemetria

Dërgoni ngjarje auditimi në kohë reale nga brenda sandbox-it në një server monitorimi të jashtëm sa herë që lexohen ose modifikohen skedarët.

  • Përputhni mjete të shumëfishta: Meqenëse përputhësit përdorin regex standard, ju mund të kombinoni mjete të shumëfishta në një rregull të vetëm duke përdorur tuba ( read_file|write_file ) ose wildcards ( .*_file ).
  • Mbani sekretet larg konfigurimit tuaj: Përcaktoni tokenët e autentifikimit në konfigurimin e rrjetit të mjedisit tuaj ( network.allowlist.transform ). Proxy-ja e daljes injekton automatikisht tokenët tuaj të vërtetë të bartësit në kërkesat dalëse.

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

PUSHTIM

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

Kufizime

  • Shtrirja e mjetit sandbox: Grepat ndërpresin mjetet e integruara brenda sandbox: ekzekutimin e kodit ( code_execution ) dhe operacionet e sistemit të skedarëve ( read_file , write_file , list_files dhe delete_file ). Ato nuk aktivizohen për thirrjen e funksioneve të personalizuara ( function ) ose mjetet e Protokollit të Kontekstit të Modelit të jashtëm ( mcp_server ) të trajtuara jashtë kontejnerit.
  • Listat e lejimeve të rrjetit: Grepat HTTP funksionojnë brenda rrjetit kontejner. Ju duhet të lejoni në mënyrë të qartë URL-të e synuara në network.allowlist të mjedisit tuaj. Adresat e loopback ( localhost , 127.0.0.1 ) bllokohen nga proxy.
  • Miratim automatik për gabimet: Nëse një skript grepi ngec (status daljeje jo zero), skadon koha ose dështon, koha e ekzekutimit regjistron dështimin dhe lejon që thirrja e mjetit të vazhdojë. Kjo siguron që skriptet e prishura të linter ose proceset e bllokuara të mos i bllokojnë kurrë aplikacionet tuaja.
  • Mbrojtja e konfigurimit të sandbox-it: Meqenëse grepat ekzekutohen brenda sandbox-it të kontejnerit, agjentët me mjete shkrimi të sistemit të skedarëve ose leje ekzekutimi të kodit të shell-it mund të modifikojnë .agents/hooks.json lokal ose skriptet brenda hapësirave të punës të shkrueshme. Përdorni grepat e kontejnerit si udhëzues të automatizuar të politikave dhe si mbrojtëse operacionale; nëse kërkohet rezistencë e rreptë ndaj ndërhyrjeve kundër ekzekutimeve të modeleve të pabesueshme, montoni burimet e konfigurimit nga depot vetëm për lexim.

Çfarë vjen më pas

,

Grepat ju lejojnë të ekzekutoni skripte të personalizuara ose kërkesa HTTP të jashtme menjëherë para ose pasi agjenti të ekzekutojë kodin ose të modifikojë skedarët brenda sandbox-it të tij të largët. Përdorni grepat për të zgjeruar ciklin e agjentit me parmakë mbrojtës të automatizuar dhe rrjedha pune në sfond, të tilla si:

  • Zbatimi i kangjellave të sigurisë dhe aksesit përpara se të ekzekutohen komandat e shell me rrezik të lartë ose leximet e kufizuara të skedarëve.
  • Automatizimi i transformimeve të tubacionit të të dhënave menjëherë pasi një agjent krijon ose modifikon skedarë.
  • Transmetimi i telemetrisë së auditimit të ndërmarrjes në sisteme monitorimi të jashtme pas ekzekutimit të mjetit.

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

PUSHTIM

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

Ngjarjet e mbështetura të ciklit jetësor

Grepat mbështesin 2 ngjarje brenda sandbox-it:

Ngjarje Kur ndizet Çfarë bën
pre_tool_execution Pak para se të funksionojë një mjet Mund ta miratojë ( allow ) ose ta bllokojë ( deny ) mjetin përpara se të ekzekutohet. Kur bllokohet, modeli e sheh arsyen e refuzimit tuaj dhe përshtatet.
post_tool_execution Menjëherë pasi mbaron një mjet Ekzekuton detyra ndjekëse si formatimi i kodit, ekzekutimi i testeve të njësisë ose regjistrimi i telemetrisë. Nuk mund të bllokojë ose zhbëjë veprimet e përfunduara.

pre_tool_execution

Aktivizohet menjëherë para se të ekzekutohet një mjet. Skripti juaj lexon detajet e thirrjes së mjetit nga stdin dhe nxjerr vendimin e tij në formatin JSON ( allow ose deny ) te stdout .

Ngarkesa hyrëse ( stdin ):

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

Përgjigja e daljes ( stdout ):

Për të miratuar thirrjen e mjetit:

{
  "decision": "allow"
}

Për të bllokuar thirrjen e mjetit dhe për të kthyer reagime te modeli:

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

Kur një grep mohon një komandë, thirrja e mjetit anashkalohet menjëherë. Agjenti sheh një rezultat gabimi që përmban arsyen e refuzimit tuaj brenda radhës së tij aktuale. Modeli më pas mund të vetëkorrigjohet duke zgjedhur një komandë alternative ose duke ia shpjeguar bllokun përdoruesit.

Nëse skripti juaj nxjerr JSON të panjohur, tekst të thjeshtë ose diçka tjetër përveç {"decision": "deny"} , koha e ekzekutimit e trajton përgjigjen si një miratim ( allow ).

post_tool_execution

Aktivizohet menjëherë pasi një mjet përfundon. Skripti juaj lexon detajet e ekzekutimit dhe çdo status gabimi nga stdin .

Ngarkesa hyrëse ( stdin ):

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

Nëse një komandë shell printon gabime në standard error ( stderr ) ose një operacion i sistemit të skedarëve dështon, një fushë "error" që përmban tekstin e gabimit përfshihet në ngarkesë. Kur komanda ka sukses pa gabime, fusha "error" lihet plotësisht jashtë.

Përgjigja e daljes ( stdout ):

{}

Meqenëse grepat post-tool funksionojnë vetëm për detyra në sfond, siç janë formatimi i kodit ose regjistrimi, koha e ekzekutimit injoron çdo vlerë vendimi të kthyer në stdout .

Zbulimi i konfigurimit

Runtime zbulon automatikisht përkufizimet e hook-eve nga .agents/hooks.json ose /.agents/hooks.json brenda mjedisit sandbox. Ju mund të ofroni hooks.json së bashku me skriptet tuaja të personalizuara duke përdorur çdo burim të mjedisit të mbështetur:

  • Montimi i depos : Një depo Git që përmban .agents/hooks.json së bashku me AGENTS.md .
  • Ruajtja në renë kompjuterike ( gcs ) : Një depo GCS që përmban hooks.json e kopjuar në mjedis.
  • Burime të brendshme : Përmbajtja e vargut dhe skriptit të papërpunuar JSON të kaluara në environment.sources gjatë thirrjes së client.interactions.create .

skema hooks.json

Një skedar hooks.json grupon përkufizimet e ngjarjeve ( pre_tool_execution ose post_tool_execution ) nën emra të personalizuar. Ju mund ta aktivizoni ose çaktivizoni secilin grup në mënyrë të pavarur:

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

Sintaksa dhe rregullat e përputhjes

Çdo grup rregullash në hooks.json përcakton se kur dhe si aktivizohen trajtuesit duke përdorur vetitë matcher dhe hooks :

Fushë Lloji Përshkrimi
enabled boolean Opsionale. Vendoseni në false për të çaktivizuar grupin ( true si parazgjedhje).
matcher string Modeli i shprehjeve të rregullta përputhet me emrat e mjeteve të synuara brenda kontejnerit.
hooks array Listë e renditur e përkufizimeve të trajtuesve ( command ose http ). Trajtuesit ekzekutohen në mënyrë sekuenciale sipas renditjes së deklarimeve.

Si funksionon vlerësimi i regex-it

Kur agjenti thërret një mjet brenda sandbox-it, koha e ekzekutimit vlerëson emrin e kontejnerit të mjetit kundrejt modelit tuaj matcher duke përdorur shprehje të rregullta standarde RE2. Nëse regex përputhet me emrin e mjetit, të gjithë trajtuesit në vargun hooks ekzekutohen me radhë. Nëse grupe të shumta rregullash përputhen me të njëjtin mjet, të gjitha vargjet përkatëse të trajtuesve ekzekutohen.

Mund të caktoni çdo emër mjeti të integruar kontejneri: ekzekutimin e kodit ( code_execution ) ose operacionet e sistemit të skedarëve ( read_file , write_file , list_files dhe delete_file ).

Shprehje të zakonshme përputhjeje

  • "code_execution" : Përputhje e saktë e vargut për komandat shell dhe ekzekutimet e skripteve.
  • "write_file" : Përputhje e saktë për krijimin e skedarëve të sistemit të skedarëve dhe shkrimet në disk.
  • "read_file|write_file" : Ndarja e tubave përputhet me emra të shumtë specifikë mjetesh në një rregull të vetëm.
  • ".*_file" : Karakteristika e egër regex përputhet me çdo mjet që mbaron me _file (si p.sh. read_file , write_file ose delete_file ). Shprehjet e rregullta standarde RE2 kërkojnë .* ; glob-et e thjeshta të shell-it si *_file janë sintaksë e pavlefshme regex dhe nuk do të përputhen.
  • ".*" ose "*" ose "" : Model gjithëpërfshirës që kap çdo thirrje të vetme të mjetit brenda kontejnerit.

Llojet e trajtuesve

Grepa komandash

Hook-et e komandave ekzekutojnë një komandë shell ose skript brenda sandbox-it. Skripti merr ngjarjen JSON në stdin dhe nxjerr vendimin e tij JSON në stdout .

Fushë Lloji Përshkrimi
type string Duhet të jetë "command" .
command string Rreshti i komandës për t'u ekzekutuar brenda sandbox-it (për shembull, python3 /.agents/hooks-scripts/gate.py ).
timeout integer Kohëzgjatja në sekonda. Parazgjedhja: 30 .

Grepa HTTP

Grepat HTTP dërgojnë ngjarjen JSON si një kërkesë POST në një URL HTTPS të jashtme direkt nga brenda rrjetit sandbox. Serveri i synuar kthen vendimin e tij në trupin e përgjigjes HTTP duke përdorur saktësisht të njëjtin format JSON ( {"decision": "allow"} ose {"decision": "deny", "reason": "..."} ).

Fushë Lloji Përshkrimi
type string Duhet të jetë "http" .
url string Pikë fundore HTTPS e jashtme për të POST-uar ngarkesën e ngjarjes.
headers object Çifte opsionale çelës-vlerë për tituj të personalizuar jo të ndjeshëm (si p.sh. {"X-Event-Source": "agent-sandbox"} ). Për kredencialet e vërtetimit, përdorni në vend të tyre proxy-n e rrjetit.
timeout integer Kohëzgjatja në sekonda. Parazgjedhja: 30 .

Transformimi i proxy-t dhe token-it të daljes

Meqenëse grepat HTTP ekzekutohen direkt nga brenda hapësirës së emrave të rrjetit sandbox, kërkesat dalëse kalojnë përmes proxy-t transparent të daljes. Kjo arkitekturë ju jep 2 avantazhe kritike sigurie:

  • Vendosja në listën e lejuar të rrjetit: Pikat fundore të synuara duhet të lejohen në mënyrë të qartë në network.allowlist të mjedisit tuaj. Trafiku i rikthimit ( 127.0.0.1 ose localhost ) bllokohet nga proxy; gjithmonë synoni pikat fundore të jashtme të listës së lejuar.
  • Transformimi i tokenëve: Nuk keni nevojë të ruani çelësa API ose tokena bartës sekretë brenda .agents/hooks.json ose t'i montoni ato në kontejner. Në vend të kësaj, konfiguroni rregullat e transformimit të tokenëve në konfigurimin e rrjetit tuaj ( network.allowlist.transform ). Proxy-ja e daljes ndërpret automatikisht trafikun dalës të HTTP hook dhe injekton kokat tuaja të vërtetimit të vërtetë në tel përpara se të largohet nga sandbox-i.

Si i trajton koha e ekzekutimit vendimet dhe dështimet

  • Pritja sinkrone: Agjenti ndalet dhe pret që goditjet tuaja të përfundojnë përpara se të vazhdojë.
  • Bllokimi i ekzekutimit të mjetit: Nëse goditja juaj paraprake e mjetit kthen {"decision": "deny", "reason": "<your reason>"} , koha e ekzekutimit anulon menjëherë thirrjen e mjetit. Modeli e sheh arsyen e refuzimit tuaj në historikun e bisedës së tij dhe përshtatet duke zgjedhur një alternativë të sigurt ose duke ia shpjeguar bllokimin përdoruesit.
  • Trajtimi i bllokimeve të skriptit, gabimeve HTTP dhe skadimeve të kohës: Nëse një skript komande bllokohet (status daljeje jo-zero), një grep HTTP kthen një kod statusi jo-2xx (siç është një gabim serveri 4xx ose 5xx), ose një operacion skadon ose kthen JSON të panjohur, koha e ekzekutimit e trajton atë si një miratim ( allow ). Ekzekutimi i mjetit vazhdon normalisht, kështu që një skript i prishur ose një server telemetrie i paarritshëm nuk e bllokon kurrë aplikacionin tuaj.

Rastet e përdorimit të zakonshëm

Rimëkëmbje me shumë kthesa për privatësinë dhe pajtueshmërinë e të dhënave

Kur një grep bllokon aksesin në burime të kufizuara - siç janë drejtoritë që përmbajnë Informacion Personal të Identifikueshëm (PII) ose të dhëna financiare konfidenciale - ju mund të kaloni previous_interaction_id në thirrjen tjetër për të vazhduar kthesën në të njëjtin mjedis. Agjenti lexon shpjegimin e refuzimit dhe rikuperohet automatikisht duke pyetur tabelat publike të miratuara në vend të kësaj.

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

PUSHTIM

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

Regjistrimi i auditimit të jashtëm dhe telemetria

Dërgoni ngjarje auditimi në kohë reale nga brenda sandbox-it në një server monitorimi të jashtëm sa herë që lexohen ose modifikohen skedarët.

  • Përputhni mjete të shumëfishta: Meqenëse përputhësit përdorin regex standard, ju mund të kombinoni mjete të shumëfishta në një rregull të vetëm duke përdorur tuba ( read_file|write_file ) ose wildcards ( .*_file ).
  • Mbani sekretet larg konfigurimit tuaj: Përcaktoni tokenët e autentifikimit në konfigurimin e rrjetit të mjedisit tuaj ( network.allowlist.transform ). Proxy-ja e daljes injekton automatikisht tokenët tuaj të vërtetë të bartësit në kërkesat dalëse.

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

PUSHTIM

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

Kufizime

  • Shtrirja e mjetit sandbox: Grepat ndërpresin mjetet e integruara brenda sandbox: ekzekutimin e kodit ( code_execution ) dhe operacionet e sistemit të skedarëve ( read_file , write_file , list_files dhe delete_file ). Ato nuk aktivizohen për thirrjen e funksioneve të personalizuara ( function ) ose mjetet e Protokollit të Kontekstit të Modelit të jashtëm ( mcp_server ) të trajtuara jashtë kontejnerit.
  • Listat e lejimeve të rrjetit: Grepat HTTP funksionojnë brenda rrjetit kontejner. Ju duhet të lejoni në mënyrë të qartë URL-të e synuara në network.allowlist të mjedisit tuaj. Adresat e loopback ( localhost , 127.0.0.1 ) bllokohen nga proxy.
  • Miratim automatik për gabimet: Nëse një skript grepi ngec (status daljeje jo zero), skadon koha ose dështon, koha e ekzekutimit regjistron dështimin dhe lejon që thirrja e mjetit të vazhdojë. Kjo siguron që skriptet e prishura të linter ose proceset e bllokuara të mos i bllokojnë kurrë aplikacionet tuaja.
  • Mbrojtja e konfigurimit të sandbox-it: Meqenëse grepat ekzekutohen brenda sandbox-it të kontejnerit, agjentët me mjete shkrimi të sistemit të skedarëve ose leje ekzekutimi të kodit të shell-it mund të modifikojnë .agents/hooks.json lokal ose skriptet brenda hapësirave të punës të shkrueshme. Përdorni grepat e kontejnerit si udhëzues të automatizuar të politikave dhe si mbrojtëse operacionale; nëse kërkohet rezistencë e rreptë ndaj ndërhyrjeve kundër ekzekutimeve të modeleve të pabesueshme, montoni burimet e konfigurimit nga depot vetëm për lexim.

Çfarë vjen më pas