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.jsonsë bashku meAGENTS.md. - Ruajtja në renë kompjuterike (
gcs) : Një depo GCS që përmbanhooks.jsone kopjuar në mjedis. - Burime të brendshme : Përmbajtja e vargut dhe skriptit të papërpunuar JSON të kaluara në
environment.sourcesgjatë 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_fileosedelete_file). Shprehjet e rregullta standarde RE2 kërkojnë.*; glob-et e thjeshta të shell-it si*_filejanë 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.allowlisttë mjedisit tuaj. Trafiku i rikthimit (127.0.0.1oselocalhost) 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.jsonose 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