Skip to content
NorthstarPlatformPricingLogin
Using Northstar

Run a Task

Give a plain language instruction and let Northstar operate a computer to complete it.

This guide shows how to run a task where Northstar operates a computer to get work done. The model sees the screen and decides what to click, type, or scroll — you just provide the instruction.

Prerequisites: Complete the Quickstart and have TZAFON_API_KEY set in your environment.

Streaming gives you real-time visibility into what’s happening on the computer:

run_task.py
from tzafon import Lightcone
client = Lightcone()
for event in client.agent.tasks.start_stream(
instruction="Open the file manager, navigate to /home, and list the contents. Then open the terminal and run 'uname -a'.",
kind="desktop",
model="tzafon.northstar-cua-fast",
max_steps=20,
):
print(event)
run_task.ts
import Lightcone from "@tzafon/lightcone";
const client = new Lightcone();
const stream = await client.agent.tasks.startStream({
instruction: "Open the file manager, navigate to /home, and list the contents. Then open the terminal and run 'uname -a'.",
kind: "desktop",
model: "tzafon.northstar-cua-fast",
max_steps: 20,
});
for await (const event of stream) {
console.log(event);
}

For background work, start async and check status periodically:

import time
from tzafon import Lightcone
client = Lightcone()
task = client.agent.tasks.start(
instruction="Open the terminal and check system resource usage with htop",
kind="desktop",
)
print(f"Task started: {task.task_id}")
# Poll for completion
while True:
status = client.agent.tasks.retrieve_status(task.task_id)
print(f"Status: {status.status}")
if status.status in ("completed", "failed"):
print(f"Exit code: {status.exit_code}")
break
time.sleep(2)
const task = await client.agent.tasks.start({
instruction: "Open the terminal and check system resource usage with htop",
kind: "desktop",
});
console.log(`Task started: ${task.task_id}`);
// Poll for completion
while (true) {
const status = await client.agent.tasks.retrieveStatus(task.task_id!);
console.log(`Status: ${status.status}`);
if (status.status === "completed" || status.status === "failed") {
console.log(`Exit code: ${status.exit_code}`);
break;
}
await new Promise((r) => setTimeout(r, 2000));
}

Inject a message to change direction while a task is running:

from tzafon import Lightcone
client = Lightcone()
task = client.agent.tasks.start(
instruction="Research the latest AI news using Firefox",
kind="desktop",
)
# After a few seconds, redirect
import time
time.sleep(5)
client.agent.tasks.inject_message(
task.task_id,
message="Actually, focus specifically on news about large language models",
)
const task = await client.agent.tasks.start({
instruction: "Research the latest AI news using Firefox",
kind: "desktop",
});
// Redirect after a delay
await new Promise((r) => setTimeout(r, 5000));
await client.agent.tasks.injectMessage(task.task_id!, {
message: "Actually, focus specifically on news about large language models",
});

Pause a task to save compute, then resume when ready:

client.agent.tasks.pause(task.task_id)
print("Task paused")
# ... later ...
client.agent.tasks.resume(task.task_id)
print("Task resumed")
await client.agent.tasks.pause(task.task_id!);
console.log("Task paused");
// ... later ...
await client.agent.tasks.resume(task.task_id!);
console.log("Task resumed");

The quality of your instruction directly affects performance.

Good instructions:

  • “Open Firefox, go to amazon.com, search for ‘mechanical keyboard’, sort by price low to high, and screenshot the first 3 results”
  • “Open the terminal, run df -h to check disk usage, then open the text editor and save the output to a file called disk-report.txt”

Vague instructions (avoid):

  • “Find something interesting online”
  • “Do some research”