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

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

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