Skip to main content
Navigator n2 is a computer-use model. It operates a full desktop. Given a task in natural language and a screenshot, it predicts the next batch of mouse and keyboard actions, and it can run shell commands directly. Use the API model id n2 in the model field of your chat.completions requests. n2 follows the OpenAI chat.completions interface. It exposes five tools — computer_batch for the GUI, edit / read / write for files, and bash for the shell — and returns its actions as tool_calls for your client to execute against the desktop.
Want to see n2 work before you write anything? Open the Playground — it runs n2 against a hosted desktop and streams the session live.Want to run n2 on your local Mac? Use Yutori MCP for the local computer-use harness and setup instructions.

Model Versions

Supported Actions

The default tool set is computer_use_tools-20260830. It contains five tools.

computer_batch

The one tool that drives the GUI. It runs a sequence of primitive actions in a single call and returns a screenshot after the last one, so it is both how the model acts and how it sees. Each item in actions is shaped {"name": <action>, "arguments": {...}}:
Three properties of a batch matter when you execute it:
  • Actions run sequentially, in order.
  • Execution stops at the first error. Remaining actions are skipped — do not continue past a failure, and report which action failed in the tool result.
  • All coordinates in a batch refer to the screenshot taken before the batch started, not to the state after any earlier action in the same batch.
Return a single tool result for the whole batch, carrying one screenshot taken after the last action executed.

Batch Actions

The current vocabulary has 15 primitive action types inside computer_batch. Coordinate-taking actions use the normalized 1000×1000 space. The Python SDK’s N2ComputerAgent accepts 1–20 actions in one batch. Parameter notes:
  • coordinates and start_coordinates are [x, y] integers in the normalized 0–1000 space, origin top-left.
  • direction for scroll is up or down. Horizontal scrolling is not available.
  • amount for scroll is an integer from 1 to 50, measured in wheel notches.
  • modifier is a single modifier key held for the duration of the action: ctrl, shift, alt, meta, command, or super. Execute it as one gesture — press, act, release. A modified click that degrades to a plain click is worse than an error, because a ctrl-click meant to extend a selection instead activates the target.
  • duration for wait and hold_key is in seconds.
  • mouse_down and mouse_up bracket a manual drag: mouse_movemouse_downmouse_movemouse_up. The button stays held across the members between them, so execute them against real press/release primitives rather than synthesizing a click. Release anything still held when the batch ends.
  • screenshot takes no arguments and acts on nothing. A batch already answers with a screenshot taken after its last action, so a screenshot member is a no-op you can skip; it exists because it is the only way the model can ask to look without acting.

bash

Runs a shell command on the desktop and returns combined stdout/stderr. Each call is a separate process. The working directory persists across calls; environment variables and shell functions do not — chain dependent steps in one command with && or ;.

read

Reads a text file and returns it in cat -n format, with the encoding detected from the byte-order mark. Relative paths resolve against the shell’s working directory. To look at an image, take a screenshot instead — the tool result channel is text.

write

Writes a file, creating it or replacing its contents. Prefer this over a bash heredoc for anything non-trivial: content rides as a JSON string, so it is never shell-escaped and a backtick or $ in the payload cannot corrupt the file.

edit

Replaces an exact string in an existing file. The file has to be read (or written) earlier in the same session first — the model is expected to know the current bytes before changing them, and your executor should enforce that rather than editing blind.

Key Space

n2 uses lowercase key names. Combinations are joined with +, and sequential presses are separated by spaces. Examples: ctrl+c, ctrl+shift+t, alt+tab, down down down enter Punctuation keys use their word formskey_press with slash, not /. To enter punctuation as text, use type instead.

Coordinate System

n2 outputs normalized coordinates in a 1000×1000 space, origin top-left. Scale them to your desktop’s real pixel resolution before executing. The model is never told the resolution.
See yutori.navigator.coordinates for the inverse normalize_coordinates function.

Screenshots

Capture the whole screen, including window borders, title bars, the taskbar, and any system UI. n2 clicks on all of it, so cropping any of it away removes targets the model needs to see. n2 reports normalized coordinates. 1920×1080, 1280×720, and 1280×800 are all in regular use. Grounding may degrade at extreme aspect ratios. Requests are capped at 10 MB, returning HTTP 413 (request_too_large) above that. Full-screen captures are large and a trajectory carries several, so compress them: WebP at ~80% quality, not PNG. A handful of uncompressed full-screen PNGs will exceed the cap on their own. The Python SDK handles encoding:
See yutori.navigator.images for resolution and quality options.

Request Fields

Supported alongside model and messages:

Sampling

Applied whenever you send nothing for a field. An explicit null counts as sending nothing: temperature: 0 is not recommended for a reasoning model. Rejected. n2 returns an error for these rather than silently ignoring them: Each returns HTTP 400 with an OpenAI-shaped error body:
max_tokens is also rejected, but as a schema violation (HTTP 422) rather than a 400.
A rejected field sent as an empty value is dropped instead of rejected — "tools": [] and "response_format": {} are accepted as no-ops. Only a non-empty value returns a 400, so an empty value is not a reliable way to probe whether a field is supported.
prompt_cache_key is accepted and then dropped before the request reaches the model. Any field outside the ones documented here is stripped rather than rejected — an unrecognized parameter will not error, and will not take effect. parallel_tool_calls is pinned to true server-side, so a value you send for it is ignored. In practice n2 answers with a single computer_batch call, which is how it chains actions against one screenshot — but it may return more than one call in a turn, and a loop has to handle that. The SDK’s N2ComputerAgent executes the first call and answers the rest with an error result, because they were planned against a screenshot that the first call has already changed. Whatever the policy, every call needs its own tool result.

Prompting

A system message you supply adds to n2’s defaults rather than replacing them, so a custom system prompt cannot override them — and extra behavioral instructions generally degrade results. Put task-specific instructions in the first user message, after the task description.

Message History

Send the full conversation. Do not drop messages — the model needs its own action history to avoid repeating work. n2 retains screenshots at the message level: the last 2 image-bearing messages keep their images, capped at 6 images within each. Older images are dropped server-side with no marker; a short placeholder is inserted only when dropping them would leave a message with no content. In practice it means n2 sees the current screen and the previous one, which is why the previous screenshot should be a real observation rather than a stale duplicate. Send the full history regardless — the text of every earlier turn is kept, and it is what the model uses to know what it has already tried. A turn looks like this — assistant message with the batch call, then one tool result carrying the post-batch screenshot:
If a batch stopped early, say so in the tool result text — which action failed, and why. For edit, read, write, and bash, return the tool’s result text or the command output the same way. When n2 is done with the task it returns content text and no tool_calls — the signal to end the loop. You can append a new user message to continue from the same history.

Context and Compaction

The served context window is 128,000 tokens. Nothing on this endpoint compacts a conversation for you: the server drops older images (see Message History) but keeps the text of every turn, so a long trajectory grows until a request no longer fits. n2 is trained for long-horizon work with a compaction step, and reproducing it is what keeps a long run in distribution: Once a response reports more than 53,760 prompt tokens, ask the model to write a checkpoint of the conversation so far, then replace the compacted turns with it and continue. A run that instead grows toward the full 128,000-token window is operating past the context the model was trained at. The Python SDK does this by default — N2ComputerAgent attaches an N2InlineCompactor unless you pass compactor=None. The compaction prompt and the reference implementation live in yutori/navigator/n2_compaction.py.

Reasoning

Reasoning is on by default, at medium effort. Set reasoning_effort to change it:
OpenAI’s high and minimal are accepted as aliases for xhigh and low. Any other value falls back to medium. chat_template_kwargs is not accepted — reasoning_effort is the supported way to set this. The trace comes back on the assistant message as reasoning_content, alongside content and tool_calls. Echo it back on the next call — append the assistant message unchanged, reasoning_content included — so the model keeps its own reasoning across turns:
Reasoning tokens bill at the output rate (see Pricing) and count against max_completion_tokens.

Tool Sets

Published dated tool sets are immutable: an id always denotes the same tool definitions, and a new surface gets a new date. The default is the current latest set (computer_use_tools-20260830), and you can select a set explicitly with the tool_set field:

Changing the tool set

The set is a fixed, immutable list, but you can drop tools from it and add your own. The two compose: disable_tools is applied first, then your definitions in tools are appended after the set’s.

Disabling a tool

Drop tools you cannot support. A host with no shell or no filesystem should say so rather than let the model call a tool that will always fail:
Only bash, read, write, and edit can be disabled. computer_batch cannot — it is the GUI surface, and without it there is no computer agent. Unknown names are rejected rather than ignored, so a typo ("shell", "bash ") fails the call instead of quietly serving the full set.

Adding custom tools

tools serves your own definitions alongside the set, in the standard OpenAI tool shape. Use it to expose capabilities the predefined tool sets do not cover:
A tool from the tool_set can also be redefined by first disabling the tool name and then providing your own definition in tools. Adding a definition in tools with a conflicting name to an existing tool in the tool_set will return a 400 if the original tool is not first disabled:
computer_batch cannot be redefined at all, for the same reason it cannot be disabled. Duplicate names within tools are rejected too.

Agent Loop

One turn: send the task and the newest screenshot, receive a tool call (usually one; see Request Fields for the case of several), execute it against the desktop, and send back one tool result per call — a screenshot for computer_batch, text for bash, read, write, and edit. Repeat until the model returns text with no tool_calls. A few tips:
  1. Unpack the batch. Read actions and turn each {"name", "arguments"} item into one call against your input driver.
  2. Denormalize coordinates against the screen resolution, per action, before executing it.
  3. Stop at the first error and report which action failed. Do not run the rest of the batch.
  4. Return one tool result per tool call, not one per action, with exactly one screenshot taken after the last executed action.
  5. Keep the payload under 10 MB by compressing screenshots.
  6. Compact long runs rather than growing to the full window — see Context and Compaction.
  7. End a capped run with a summary. If you cap the number of turns, spend the last one on a user message asking the model to stop and summarize its progress; a run cut off mid-trajectory otherwise returns no final answer.
Some helpers in the Python SDK: The SDK exports TOOL_SET_COMPUTER_USE_LATEST so you can pin the tool set without hardcoding a date string. It tracks the SDK release rather than the server default, so check the constant’s value in the version you install. See Tool Sets.