Gemini — Computer Use (tools[].computerUse, Preview)
Status: DOCUMENTED + ACCOUNT_RESTRICTED (2026-09-18: our key got HTTP 429 quota errors — see "Live verification" section at the end)
Sources:
- https://ai.google.dev/gemini-api/docs/generate-content/computer-use · https://ai.google.dev/gemini-api/docs/computer-use
- https://ai.google.dev/api/generate-content (#ComputerUse #Environment #SafetyPolicy)
- https://ai.google.dev/gemini-api/docs/models/gemini-2.5-computer-use-preview-10-2025 · https://ai.google.dev/gemini-api/docs/pricing · https://ai.google.dev/gemini-api/docs/changelog
- Reference implementation: https://github.com/google/computer-use-preview
Last verified: 2026-09-18 (docs only)
1. Models
| Model | Notes |
|---|---|
gemini-3.8-flash |
recommended; high-accuracy UI interaction |
gemini-3.7-flash, gemini-3.5-flash, gemini-3.5-flash-lite, gemini-3-flash-preview |
Gemini 3.x feature set (intents, 3 environments, safety policies, prompt-injection detection from 3.5 Flash) |
gemini-3.6-flash, gemini-robotics-er-2-preview, gemini-robotics-er-1.6-preview |
"Supported (Preview)" on model pages, not in the guide list |
gemini-2.5-computer-use-preview-10-2025 |
legacy; browser only; 128k input / 64k output; image + text input |
gemini-3-pro-preview |
model page: Not supported (changelog 2025-11 said launched) — conflict |
2. Tool config (tools[].computerUse)
| Field | Type | Notes |
|---|---|---|
environment |
enum, required | ENVIRONMENT_BROWSER, ENVIRONMENT_MOBILE, ENVIRONMENT_DESKTOP (ENVIRONMENT_UNSPECIFIED → browser). Mobile/desktop: Gemini 3.x |
excludedPredefinedFunctions[] |
string[] | drop predefined actions (restrict action space or replace with your own declaration) |
enablePromptInjectionDetection |
bool (default false) | Gemini 3.5 Flash+: scan screenshots for hidden instructions; blocks execution when detected |
disabledSafetyPolicies[] |
SafetyPolicy[] |
FINANCIAL_TRANSACTIONS, SENSITIVE_DATA_MODIFICATION, COMMUNICATION_TOOL, ACCOUNT_CREATION, DATA_MODIFICATION, USER_CONSENT_MANAGEMENT, LEGAL_TERMS_AND_AGREEMENTS — preferences only; require_confirmation may still be returned |
Extra: add tools[].functionDeclarations for custom actions (e.g. yield_to_user(reason)); tune generationConfig.thinkingConfig.thinkingLevel (lower = faster). No display size needed — coordinates are normalized 0–999 and you scale them to your viewport.
3. Predefined actions (functionCall names)
Browser (ENVIRONMENT_BROWSER, Gemini 3.x)
| Action | Args (all + intent: str) |
|---|---|
click, double_click, triple_click, middle_click, right_click, mouse_down, mouse_up, move |
x, y (0–999) |
type |
text, press_enter (default false) |
drag_and_drop |
start_x, start_y, end_x, end_y |
wait |
seconds (default 1) |
press_key, key_down, key_up |
key |
hotkey |
keys: list[str] |
take_screenshot |
— |
scroll |
x, y, direction: up|down|left|right, magnitude_in_pixels (default 300) |
go_back, go_forward |
— |
navigate |
url |
Mobile (ENVIRONMENT_MOBILE): open_app(app_name), click, list_apps, wait, go_back, type, drag_and_drop, long_press(x,y,seconds=2), press_key, take_screenshot.
Desktop (ENVIRONMENT_DESKTOP): browser set minus go_back/navigate/go_forward.
Legacy (gemini-2.5-computer-use-preview-10-2025)
| Action | Args |
|---|---|
open_web_browser, wait_5_seconds, go_back, go_forward, search |
none |
navigate |
url |
click_at, hover_at |
x, y (0–999) |
type_text_at |
x, y, text, press_enter (default true), clear_before_typing (default true) |
key_combination |
keys e.g. "Control+A" |
scroll_document |
direction |
scroll_at |
x, y, direction, magnitude (default 800) |
drag_and_drop |
x, y, destination_x, destination_y |
4. Safety decisions
Model: functionCall.args.safety_decision = {"decision": "require_confirmation", "explanation": "..."} (regular/allowed, require_confirmation, or blocked). Client: prompt the user; if confirmed, include "safety_acknowledgement": true in the functionResponse response object; otherwise terminate. Always implement this handling regardless of disabledSafetyPolicies.
5. Loop (pseudo-code, Playwright)
from playwright.sync_api import sync_playwright
from google import genai; from google.genai import types
client = genai.Client(); W, H = 1440, 900
cfg = types.GenerateContentConfig(tools=[types.Tool(computer_use=types.ComputerUse(environment="ENVIRONMENT_BROWSER"))])
with sync_playwright() as p:
page = p.chromium.launch().new_context(viewport={"width": W, "height": H}).new_page(); page.goto("https://www.google.com")
history = [types.Content(role="user", parts=[types.Part(text="Search for 'Gemini API'."),
types.Part.from_bytes(data=page.screenshot(type="png"), mime_type="image/png")])]
for _ in range(10):
r = client.models.generate_content(model="gemini-3.8-flash", contents=history, config=cfg)
history.append(r.candidates[0].content) # keeps thoughtSignature + id
calls = [pt.function_call for pt in r.candidates[0].content.parts if pt.function_call]
if not calls: break
responses = []
for fc in calls:
a = dict(fc.args); result = {}
if "safety_decision" in a: result["safety_acknowledgement"] = True # after asking the user!
if fc.name in ("click", "click_at"): page.mouse.click(a["x"] / 1000 * W, a["y"] / 1000 * H)
elif fc.name in ("type", "type_text_at"):
if "x" in a: page.mouse.click(a["x"] / 1000 * W, a["y"] / 1000 * H)
page.keyboard.type(a["text"]); a.get("press_enter") and page.keyboard.press("Enter")
elif fc.name == "navigate": page.goto(a["url"])
elif fc.name == "scroll": page.mouse.wheel(0, a.get("magnitude_in_pixels", 300) * (1 if a["direction"] == "down" else -1))
page.wait_for_load_state("load", timeout=5000)
responses.append(types.Part(function_response=types.FunctionResponse(name=fc.name, id=fc.id,
response={"url": page.url, **result},
parts=[types.FunctionResponsePart(inline_data=types.FunctionResponseBlob(mime_type="image/png", data=page.screenshot(type="png")))])))
history.append(types.Content(role="user", parts=responses))The official guide's get_function_responses sample returns the screenshot as an image content block alongside {"url": current_url, ...}; the generateContent shape is functionResponse.parts[].inlineData (Gemini 3 multimodal function responses).
6. Pricing / limits / security
- Pricing: regular model token pricing (screenshots = image tokens); free tier not available; legacy 2.5 CU model has its own table.
- Preview: "may contain errors and security vulnerabilities" — avoid critical decisions, sensitive data, irreversible actions.
- Run in a sandboxed VM/container (reference Docker sandbox); human-in-the-loop on
require_confirmation; custom safety system instructions; enable prompt-injection detection where available; not in the Live API.
7. Minimal request
curl -s "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.5-flash-lite:generateContent" \
-H "x-goog-api-key: $GEMINI_API_KEY" -H "Content-Type: application/json" \
-d '{"contents":[{"parts":[{"text":"Search for Gemini API on Google."}]}],"tools":[{"computerUse":{"environment":"ENVIRONMENT_BROWSER"}}]}'const r = await ai.models.generateContent({ model: 'gemini-3.5-flash-lite', contents: "Search for 'Gemini API' on Google.",
config: { tools: [{ computerUse: { environment: 'ENVIRONMENT_BROWSER', excludedPredefinedFunctions: ['drag_and_drop'] } }] } });
console.log(r.functionCalls);Live verification (2026-09-18)
- Legacy generateContent tool
tools:[{"computerUse":{"environment":"ENVIRONMENT_BROWSER"}}]ongemini-2.5-computer-use-preview-10-2025with a 1×1 PNG → HTTP 429Quota exceeded for metric: generativelanguage.googleapis.com/generate_content_free_tier_input_token_count, limit: 0, model: computer-use-preview→ ACCOUNT_RESTRICTED (tmp-live/gemini-tools/f_computer_use_generateContent.json). - Interactions API
tools:[{"type":"computer_use","environment":"browser"}]ongemini-3.5-flash-lite, input "Do nothing. Reply DONE." → HTTP 200,status:"completed", steps[thought, model_output "DONE"]— the tool declaration is accepted on a non-computer-use model; no action was requested so thefunction_callshape was not observed live (f2_computer_use_interactions.json). - The client loop (Playwright,
function_resultwith screenshot + url,safety_decisionacknowledgement) inexamples/gemini/tools/computer-use/computer_use_interactions.py --loopis DOCUMENTED, not executed.