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.
Start a task with streaming
Section titled “Start a task with streaming”Streaming gives you real-time visibility into what’s happening on the computer:
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)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);}Fire and poll
Section titled “Fire and poll”For background work, start async and check status periodically:
import timefrom 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 completionwhile 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 completionwhile (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));}Steer mid-task
Section titled “Steer mid-task”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, redirectimport timetime.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 delayawait 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 and resume
Section titled “Pause and resume”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");Writing good instructions
Section titled “Writing good instructions”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 -hto 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”
See also
Section titled “See also”- Tasks — configuration options, pause/resume, and message injection
- Legacy software — automate enterprise applications through the GUI
- Cross-app workflows — move data between applications
- Computer-use loop — build your own loop for more control