Vis

Drafts API

Turn on drafts, read the draft state of a session and control draft work from your own program. The agent in the session still creates, approves and discards each draft.

The examples use the Python SDK. To see the same steps as HTTP API requests, select HTTP at the top of the page.

When to use

To learn how drafts isolate changes, read Drafts.

Before you start

Python

Connect a GatewayClient as in Connect to a gateway and run a task. The examples use client and session, a Session from client.session(session_id).

HTTP

Define the vis_api function from Authenticate requests. The examples use it. They also use SESSION_ID for the ID of a session that you created or found.

Drafts are experimental and off by default. Approval commits and can push. Your program must have the permission of the person who owns the repository.

Operations

Python

Typed calls check the answers and return records. Generated methods return the JSON answer of one request.

Task Typed call Generated method
Turn on drafts — post_settings(body=...)
Read the draft state — get_session_workspace(sid)
Ask for work in a draft session.send(request) post_session_turns(sid, body=...)
Approve or discard a draft session.send(request) post_session_turns(sid, body=...)
Return to the original checkout — patch_session_workspace_root(sid, body=...)

HTTP

Task Method and path
Turn on drafts POST /v1/settings
Read the draft state GET /v1/sessions/{sid}/workspace
Ask for work in a draft POST /v1/sessions/{sid}/turns
Approve or discard a draft POST /v1/sessions/{sid}/turns
Return to the original checkout PATCH /v1/sessions/{sid}/workspace/root

Turn on drafts

Python

client.post_settings(
    body={"scope": "project", "target_id": project_id, "id": "draft_backend", "action": "value", "value": "auto"}
)

HTTP

vis_api -X POST "$VIS_GATEWAY_URL/v1/settings" -H 'content-type: application/json' --data "{\"scope\": \"project\",
  \"target_id\": \"$PROJECT_ID\", \"id\": \"draft_backend\", \"action\": \"value\", \"value\": \"auto\"}"

The draft_backend setting is off, auto, worktree or rift. Enable drafts explains each backend. Configuration API explains the scopes.

Read the draft state

Python

workspace = client.get_session_workspace(session.id)["workspace"]
print(workspace["is_draft"], workspace["root"], workspace["repo_root"])
print(workspace.get("branch"), workspace.get("draft_changes"))

The answer has the root of the session, the repo_root of its project and the git state. In a draft, it also has the draft branch, the repositories, the draft_changes and the working_changes. These summaries refresh in the background. A summary that is not ready yet is missing, never zero.

HTTP

vis_api "$VIS_GATEWAY_URL/v1/sessions/$SESSION_ID/workspace"

The answer has workspace with the root of the session, the repo_root of its project, is_draft and the git state. In a draft, it also has the draft branch, the repositories, the draft_changes and the working_changes. These summaries refresh in the background. A summary that is not ready yet is missing, never zero.

recovery_required is true when the session opened a directory of another draft. draft_error then explains the problem.

Ask for work in a draft

Python

turn = session.send("Fix the parser and run the tests. Do not commit or push until I approve.")
print(turn.wait(timeout=1800)["status"])

HTTP

vis_api -X POST "$VIS_GATEWAY_URL/v1/sessions/$SESSION_ID/turns" -H 'content-type: application/json' \
  --data '{"request": "Fix the parser and run the tests. Do not commit or push until I approve.", "idempotency_key": "parser-1"}'

With drafts on, the agent starts each change in a draft of its own. Your files stay unchanged.

Approve or discard a draft

Python

session.send("Show me the diff of the draft.").wait(timeout=300)
session.send("Approve the draft.").wait(timeout=600)

HTTP

vis_api -X POST "$VIS_GATEWAY_URL/v1/sessions/$SESSION_ID/turns" -H 'content-type: application/json' \
  --data '{"request": "Approve the draft.", "idempotency_key": "parser-approve-1"}'

Approval commits the changes, moves the target branch forward and pushes when origin is configured. To drop the changes, send Discard the draft. instead. Unapproved changes are then lost. Approval explains the checks before a commit.

Return to the original checkout

Python

workspace = client.patch_session_workspace_root(session.id, body={"path": "/Users/me/projects/app"})
print(workspace["workspace"]["root"])

This call does the same as /cd. It moves the session to another directory and returns the new workspace. The directory of the draft and its files stay unchanged.

HTTP

vis_api -X PATCH "$VIS_GATEWAY_URL/v1/sessions/$SESSION_ID/workspace/root" \
  -H 'content-type: application/json' --data '{"path": "/Users/me/projects/app"}'

This request does the same as /cd. It moves the session to another directory and returns the new workspace. The directory of the draft and its files stay unchanged.

See also

  • Drafts — backends, approval and recovery.
  • Python SDK — install the SDK, connect a client and handle gateway errors.
  • HTTP API — authentication, the OpenAPI document and gateway errors.