Overview

The computer-use engine in domains/computer-use/core runs ACI runs: it looks at the screen, asks a model for the next step, runs that step and looks again (the planning loop, core/planning_loop.py). Since the computer toolset work (P4), every model path speaks one action vocabulary, the Allternit computer toolset contract (allternit.computer.v1 and allternit.browser.v1), and every action runs on one executor in allternit-api.

One action vocabulary for every model

A plan’s immediate_action is one contract call:
  • Member names and input fields are the same as Claude’s computer_toolset_20260801 and browser_toolset_20260801 sets. The generated types live in contracts/toolset_v1.py.
  • The planning JSON schema (ACTION_PLAN_JSON_SCHEMA) is generated from the contract by core/toolset_executor.py. The engine keeps no copy of the action schema of its own.
  • Older verbs that some models still emit (click, goto, press, fill, …) are mapped onto members in one place, VisionAction in core/vision_providers.py. A verb that is not a member stays as it is for the selector batch path (core/batch_dispatch.py) and is never guessed into an action.

Actions run on the shared executor

When the engine runs next to allternit-api (Allternit Desktop sets ALLTERNIT_API_URL for the sidecar), each observation and action is a call to POST /api/v1/computers/:id/toolset:
  • :id is options.computerId from the run, or this-device. Browser runs pass the engine session as browser_session_id.
  • The caller is the run’s owner. allternit-api adds options.userId to the ACI run, and the Desktop gives the sidecar its desktop access token. A cloud runtime uses its internal service token instead.
  • The executor validates the call, scales coordinates between the model frame and the screen, classifies risk, writes the audit row and dispatches. The engine does no coordinate scaling or screenshot resizing of its own, and its screenshots come from the executor’s screenshot member, already in the model frame.
  • A 409 approval_required reply goes through the run’s own approval flow (the ACI approval card). After a person approves, the engine approves the grant (POST /api/aci/handoff/:id/approve) and retries the call once with it.
  • A pointing action planned on a screenshot older than max_snapshot_age_s (120 seconds by default) is refused, and the loop looks at the screen again before acting.
For browser targets, the executor forwards each browser member to the gateway’s POST /v1/toolset/browser (gateway/toolset_browser.py). It runs the member with Playwright on the session’s tabs, never calls the executor, and returns the tab inventory (browser_state) with every reply. See Browser results. Only the planning loop calls the executor, so a call can’t loop from the executor to the gateway and back. Without ALLTERNIT_API_URL (tests), the engine runs the same contract calls on its in-process adapter waterfall.

Removed endpoints (2026-10-09)

POST /v1/computer (the old Claude-native payload), POST /v1/run/hybrid and POST /v1/run/parallel were removed. Callers send one contract call to POST /api/v1/computers/:id/toolset instead (see Computer toolset). Browser sessions still use POST /v1/execute.

SDK drivers

core/toolset_driver.py has ExecutorComputerToolset and ExecutorBrowserToolset, subclasses of the Anthropic SDK’s BetaAsyncAbstractComputerToolset20260801 and BetaAsyncAbstractBrowserToolset20260801. Every member calls the executor. The SDK confirm callback is the person in the approval flow: it is asked when the executor answers 409, and a yes approves the grant and retries.