Freestyle Docs

Freestyle / Guides

How to Run Omnara Agents in a Freestyle VM

Connect a Freestyle machine pool to Omnara, launch an agent, and pause idle VMs with their state intact.

Omnara is an open-source platform for running agents with your choice of models, tools, and machines. Its native Freestyle provider creates a full Linux VM for each pool machine, installs the Omnara daemon, and reconnects it when the agent needs to work again.

This guide connects your Freestyle account to Omnara Cloud. Omnara runs the agent loop and model calls; Freestyle runs the commands, processes, and file operations. Your model credentials stay in Omnara, and VM usage is billed to your Freestyle account.

Requirements

Run the commands below on your computer. Omnara provisions the VM itself; you do not need to create one first or install the Freestyle SDK.

Create a Freestyle API Key

Create a dedicated key so you can revoke Omnara’s access separately from your other integrations:

npx freestyle@latest login
npx freestyle@latest tokens create "omnara"

Save the key ID for cleanup, and export the token shown by the second command:

export FREESTYLE_API_KEY="your-freestyle-api-key"

You can also create the key in the Freestyle dashboard. The CLI authentication guide covers API keys and revocation.

Select Your Omnara Project

npx omnara@latest login
npx omnara@latest config select

Approve the browser login, then select your organization and its Default project. On Omnara Cloud, that project already has access to the hosted omnara-openrouter model provider used below.

Pools belong to the organization. Creating a pool and granting it to the selected project are separate steps.

Store the Freestyle Key in Omnara

Create an organization-owned secret:

npx omnara@latest secrets create \
  --owner-kind org \
  --name freestyle-api-key \
  --material-kind generic \
  --material-value "$FREESTYLE_API_KEY"

Copy the secret ID beginning with sec_ from the output. The pool references that ID so Omnara can provision and manage VMs. Do not add the Freestyle key to the agent’s instructions or machine environment variables.

Create the Freestyle Pool

Save this as freestyle-pool.json, replacing sec_replace_me with the secret ID:

{
  "name": "freestyle-pool",
  "provider": "freestyle",
  "provider_auth_secret_id": "sec_replace_me",
  "default_machine_provider_options": {
    "snapshot": "freestyle/ubuntu-sm",
    "sleep_after_ms": 30000
  },
  "default_machine_cpu": 2,
  "default_machine_memory_mb": 4096,
  "min_machine_cpu": 2,
  "min_machine_memory_mb": 4096,
  "max_machine_cpu": 4,
  "max_machine_memory_mb": 8192,
  "max_total_cpu": 8,
  "max_total_memory_mb": 16384,
  "max_total_machines": 2,
  "default_cwd": "/home/ubuntu",
  "delete_after_idle_minutes": 0
}

This pool uses the Ubuntu small base snapshot: 2 vCPU, 4 GiB RAM, and a 16 GB disk. Omnara can grow a machine to the requested CPU and memory within the pool limits. It cannot shrink a snapshot, so the minimums must be at least the snapshot’s size. The disk keeps the snapshot’s size.

Freestyle’s VM start times are consistent enough that you generally do not need to keep any machines in a warm pool. Provision machines on demand and let idle VMs sleep.

sleep_after_ms asks the Omnara daemon to sleep after 30 seconds without active command or process work. The minimum is 30000; omit it to keep machines awake. delete_after_idle_minutes: 0 disables idle deletion, so this example keeps a sleeping machine available until you archive the agent or otherwise delete the machine.

Create the pool:

npx omnara@latest pools create --body "$(cat freestyle-pool.json)"

Copy the pool ID beginning with mpo_ from the output, then grant it to the project you selected:

export OMNARA_FREESTYLE_POOL_ID="mpo_replace_me"
npx omnara@latest grant pools add \
  --machine-pool-id "$OMNARA_FREESTYLE_POOL_ID"

Omnara installs omnarad as a systemd service and configures the VM’s networking, including the wake route when sleep is enabled. You do not need to set up SSH or a public application domain yourself.

Launch an Agent

Save this as agent.yaml:

version: v1
instruction: |
  You are an engineering assistant with a persistent Freestyle VM.
  Use your machine to run commands and work with files.
model:
  provider_config: omnara-openrouter
  name: openai/gpt-6.1-sol
machine_sources:
  - machine_pool_name: freestyle-pool

The machine source adds Omnara’s command, process, and file tools. Launch the agent with a task that writes a file:

npx omnara@latest agents launch \
  --file agent.yaml \
  --name "Freestyle demo" \
  --message "Run uname -a, report the kernel version, and write the current date to /tmp/freestyle-omnara-note.txt."

Copy the agent ID beginning with agt_, then follow its progress:

export OMNARA_FREESTYLE_AGENT_ID="agt_replace_me"
npx omnara@latest agents chat "$OMNARA_FREESTYLE_AGENT_ID"

You can also open the conversation in the Omnara dashboard. In Freestyle, look for a VM whose omnara-machine metadata matches the Omnara machine ID (mch_...).

Check Pause and Resume

After the task finishes, return to your shell and leave the agent idle for about two minutes, then list the pool’s machines:

npx omnara@latest machines list \
  --machine-pool-id "$OMNARA_FREESTYLE_POOL_ID"

Omnara reports connection_state: asleep after the daemon goes idle. Freestyle’s VM pause happens after its own idle timeout, so the VM can remain running briefly after Omnara reports it asleep. Check for paused in the Freestyle dashboard without opening a VM shell, which would wake it.

Send another task:

npx omnara@latest agents input "$OMNARA_FREESTYLE_AGENT_ID" \
  --message "Print /tmp/freestyle-omnara-note.txt without rewriting it."

Omnara wakes the same VM, and the agent should print the date saved before it slept. Freestyle pause and resume preserves memory, files, and running processes. Deleting a machine is different: its replacement starts from the pool’s original snapshot.

Use a Custom Snapshot

Use a custom snapshot when every agent should start with the same tools, repository checkout, or dependencies. Build it before Omnara installs its daemon, then replace snapshot in the pool configuration with its slug or ID and adjust the CPU and memory minimums to match.

The snapshot must run systemd and include a POSIX shell, curl, base64, and sha256sum or shasum. Freestyle’s Ubuntu snapshots meet these requirements.

Do not snapshot a machine that has already run omnarad for use as a pool template. Clones would inherit that machine’s identity and credentials. For setup that should run on each new machine, use Omnara’s optional startup_script provider option instead; it runs again when the daemon service starts, so make it safe to rerun.

Clean Up

Copy out any VM files you want to keep, then archive the demo agent:

npx omnara@latest agents archive "$OMNARA_FREESTYLE_AGENT_ID"

Archiving deletes its pool machines and their VM files. The conversation and uploaded artifacts remain in Omnara. Check the Freestyle dashboard to confirm the VM has been removed.

The pool and secret remain available for future agents. To remove this integration completely after its agents are archived:

npx omnara@latest pools delete "$OMNARA_FREESTYLE_POOL_ID"
npx omnara@latest secrets delete sec_replace_me
npx freestyle@latest tokens revoke freestyle-key-id

Use the Omnara secret ID and Freestyle key ID saved during setup. Revoking the Freestyle key before Omnara finishes deleting its machines prevents it from cleaning them up.

Troubleshooting

SymptomWhat to check
The agent cannot find freestyle-poolRun config select again and confirm the pool was granted to that project.
Provisioning failsCheck the Freestyle key, snapshot slug or ID, account quota, and pool limits. CPU and memory must be at least the snapshot’s size.
A custom snapshot never connectsCheck its systemd and bootstrap tools, and rebuild from a snapshot that has never run omnarad.
The machine does not sleepConfirm sleep_after_ms is set. Commands or processes started by the agent keep its machine awake while they run. Allow time for Freestyle’s idle pause after Omnara reports asleep.
A self-hosted Omnara machine never connectsSet OMNARA_PUBLIC_API_URL to an API URL reachable from the public internet. The provider permits public egress; a localhost or private-only endpoint is unreachable from the VM.

References

esc