Skip to main content

VirtuAI CLI

Run VirtuAI agents from your terminal — chat interactively in a Claude-Code-style TUI, or pipe them into shell scripts. The agent's bash/file tools run on your machine, so files appear in your filesystem and commands hit your real shell.

Installation

pip install virtuai-cli

Or with pipx (recommended for CLI tools — handles PATH automatically):

pipx install virtuai-cli

For local model inference (running agents against Ollama on your machine — see below), install the local extra:

pip install 'virtuai-cli[local]'      # or: pipx install 'virtuai-cli[local]'

Requires Python 3.11+.

Quick start

1. Pair this machine with a workspace

Open the VirtuAI portal → Settings → CLI → generate a pairing code, then:

virtuai pair <CODE>

The pairing is one-time; the resulting token is stored in your system keychain.

2. Chat with an agent

virtuai chat

Opens an interactive TUI. Pick an agent (skipped if your workspace has only one), type a message, watch the response stream in. The agent's tool calls — bash, file reads, file writes — execute on this machine, in the current directory.

Every workspace includes a built-in Plan agent. Switch to it without leaving the TUI:

/plan

/agent Plan does the same thing. List agents with /agents. Switching starts a new conversation with that agent (history does not carry over). You can also launch Plan directly: virtuai chat --agent Plan. Plan explores the repo and produces a design; it does not implement. Switch back with /agent <name> to execute.

3. Use it from a shell script

virtuai ask "summarize the changes in this branch"

git diff | virtuai ask "what does this change?"

virtuai ask --json "find any bugs" > events.jsonl

ask is non-interactive: it prints the response to stdout, then exits.

Local model inference (Ollama)

Agents can run inference on your own machine via Ollama instead of a cloud provider — useful for cost, data locality, or running open models. Only the model turns are proxied to your machine over the CLI's WebSocket; the agent loop, tools, knowledge bases, and chat history stay on the server.

To use it:

  1. Install the CLI with the local extra (pulls langchain-ollama):
    pip install 'virtuai-cli[local]'
    
  2. Install Ollama, start it, and pull a tool-capable model:
    ollama serve
    ollama pull qwen3:8b          # instruct/agentic models work best for tool calling
    
  3. In the VirtuAI portal, set the agent's Provider to Local (Ollama), enter the model tag you pulled, and pick a cloud fallback model.
  4. Connect the CLI (virtuai chat, virtuai ask, or virtuai run) — model turns are now answered by your local Ollama.

The CLI talks to Ollama at http://localhost:11434 by default; override with the OLLAMA_BASE_URL environment variable.

If the CLI isn't connected, Ollama isn't running, or the model isn't pulled, the agent falls back to its configured cloud model and shows a notice. For reliable tool use, prefer instruct/agentic models (e.g. qwen3:*, qwen2.5:*); some code-tuned or non-instruct models emit tool calls as plain text and won't drive the agent's tools.

Commands

Command Description
virtuai chat Open the interactive chat TUI
virtuai ask "..." One-shot prompt for scripts (reads stdin if piped)
virtuai pair <code> Pair this machine with a workspace
virtuai unpair Revoke the current pairing
virtuai run Headless WebSocket runner — let the web app/channels invoke local tools without opening the TUI
virtuai status Show pairing and connection status
virtuai logs Show recent commands the agent executed locally
virtuai login Authenticate with your VirtuAI account (browser flow)
virtuai config get/set Read or set local CLI options (e.g. server_url)

Inside virtuai chat

The TUI streams tokens, renders tool calls as live cards (running → complete), tracks the agent's todo list, and shows a randomized "✻ Pondering…" indicator while the agent is composing.

Slash commands (type / to see the filtered list, Tab to autocomplete):

Slash command What it does
/help Show this list
/clear, /new Drop the current session and start fresh
/history List your recent conversations with this agent
/load <id> Reopen a past conversation by session_id
/plan Switch to the built-in Plan agent
/agents List agents in this workspace
/agent <name> Switch agent without exiting (starts a new conversation)
/models List models available for this agent
/model <id> Switch the model for subsequent messages
/exit, /quit Close the TUI

Key bindings:

  • Esc — cancel the in-flight response
  • Ctrl+L — start a new conversation
  • Ctrl+C — quit
  • Tab — autocomplete the current /command

virtuai ask for scripting

# Direct prompt
virtuai ask "what's in this folder?"

# Pipe stdin in (concatenated with the argument if both given)
git log --oneline -20 | virtuai ask "summarize these commits"

# Continue a previous session (use --print-session to surface the id)
virtuai ask --session sess-aaa "and apply that fix" --print-session

# Machine-readable: every event as one JSON line
virtuai ask --json "find any bugs" > events.jsonl

# Just the final answer, no streaming (good for capturing into variables)
ANSWER=$(virtuai ask -q "give me the current time")

# Pick a different agent or model
virtuai ask --agent code-review --model claude-opus "review main.py"

# Skip the local runner for a faster startup when no tools are needed
virtuai ask --no-tools "tell me a joke"

Output streams:

  • stream (default) — tokens go to stdout, tool indicators to stderr (so > out.txt captures only the answer)
  • --quiet / -q — accumulate, print only the final assistant text at the end
  • --json — every SSE event as one JSONL line on stdout (parseable)

Exit codes: 0 success · 1 stream error · 2 bad args / agent not found.

Common options

--server <url>       Override the saved server URL
--workdir <path>     Working directory for tool execution (default: current dir)
--agent <id|name>    Pick a specific agent
--model <id>         Override the agent's default model

Security model

Read this section before pointing an agent at anything you care about.

The CLI runs the agent's shell commands as your user account, with your full filesystem permissions. There is no sandbox. The agent can do anything you can do at the shell. The guardrails below are best described as speed bumps, not walls.

What is enforced

  • Auth: CLI token is stored in your OS keychain (Keychain on macOS, libsecret on Linux, Credential Manager on Windows). All traffic is TLS (WSS + HTTPS) with the certifi CA bundle.
  • File-tool path jail: the deepagents file tools — write_file, edit_file, read_file — route through upload_files/download_files, which reject absolute paths outside the workdir. This part works.
  • cd jail in bash: the executor wraps every shell command in a bash subshell with a custom cd function that refuses to leave the workdir. Catches the trivial cd .. case.
  • Denylist: a regex match on the command string blocks sudo, rm -rf /, fork bombs, mkfs, dd of=/dev/.... Easy to bypass with aliasing or encoding; mostly there to stop drive-by accidents.
  • Audit log: every executed command + exit code goes to ~/.virtuai/audit.log with a timestamp.
  • Foreground-only: the agent only has access while virtuai chat, virtuai ask, or virtuai run is running — no background daemon.

What is NOT enforced

  • Shell commands can use absolute paths anywhere. The cd jail only intercepts cd. cat /etc/passwd, ls /Users/you/Documents, rm /tmp/whatever — none of these touch cd, so none are blocked. The agent can read, write, and delete anything you can.
  • The cd jail itself is bash-only. sh -c '...', python -c "os.chdir('/')", node -e "..." all bypass it.
  • Command substitution, eval, env vars, aliases all defeat the denylist. $(echo s)$(echo udo) ... looks nothing like sudo to a regex.
  • Network egress is not restricted. The agent can curl/wget anywhere, exfiltrate to any host.

If you need real isolation

The only honest options:

  1. Run the CLI inside a container with the workdir bind-mounted and nothing else:
    docker run --rm -it -v "$PWD:/work" -w /work python:3.12 bash -c "pip install virtuai-cli && virtuai pair <code> && virtuai chat"
    
    The container has access only to what you mount.
  2. OS-level sandboxing: wrap virtuai run in sandbox-exec on macOS or run inside a landlock/bubblewrap jail on Linux.
  3. Switch the agent's backend to the E2B remote sandbox in the portal. The agent then runs against a disposable VM, not your laptop. The CLI runner becomes optional (you'd only need it for "interactive" workflows where local files matter).

Use the CLI runner the same way you'd use a powerful shell session you don't fully trust. Point it at a project directory, never at ~, and don't run unattended on a machine with credentials lying around.

Programmatic use

The async building blocks the TUI is built on are importable directly:

import asyncio
from virtuai_cli import config as cfg
from virtuai_cli.chat.sse import stream_chat

async def main():
    token  = cfg.load_token(cfg._KEYRING_CLI_TOKEN_KEY)
    server = cfg.get_server_url()
    async for event in stream_chat(server, token, "your-agent-id", "Hello"):
        if event.get("type") == "token":
            print(event["content"], end="", flush=True)

asyncio.run(main())

A formal SDK (typed client class, sync wrappers) is on the roadmap.

Links

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

virtuai_cli-0.8.13.tar.gz (52.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

virtuai_cli-0.8.13-py3-none-any.whl (53.4 kB view details)

Uploaded Python 3

File details

Details for the file virtuai_cli-0.8.13.tar.gz.

File metadata

  • Download URL: virtuai_cli-0.8.13.tar.gz
  • Upload date:
  • Size: 52.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.6

File hashes

Hashes for virtuai_cli-0.8.13.tar.gz
Algorithm Hash digest
SHA256 a81e4df1edc6e19a09891730e6d231807bec39b8af7e6212d42b508fe1e8875a
MD5 89a84d110ea3b7b58a1ff5bd0047a282
BLAKE2b-256 2a2792f246d0b0fc902b1c58d8a8520ba957917f59a081426b20e80f67dc69d0

See more details on using hashes here.

File details

Details for the file virtuai_cli-0.8.13-py3-none-any.whl.

File metadata

  • Download URL: virtuai_cli-0.8.13-py3-none-any.whl
  • Upload date:
  • Size: 53.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.6

File hashes

Hashes for virtuai_cli-0.8.13-py3-none-any.whl
Algorithm Hash digest
SHA256 06b02b5cdebb01832948ea86cd0d19cd3cc88f47f3c92a5edbdc982feecb7694
MD5 df2ae82ee8b57cd30cf0afda663109b1
BLAKE2b-256 9fe5cd1b096de96cee1d5b8a7c6d49fad95e616082eb8f733f2878b091d6f465

See more details on using hashes here.

Release history Release notifications | RSS feed

0.8.16

2 files

0.8.15

2 files

0.8.14

2 files

This release

0.8.13 This release

2 files

0.8.12

2 files

0.8.11

2 files

0.8.10

2 files

0.8.9

2 files

0.8.8

2 files

0.8.7

2 files

0.8.6

2 files

0.8.5

2 files

0.8.4

2 files

0.8.3

2 files

0.8.2

2 files

0.8.1

2 files

0.8.0

2 files

0.7.7

2 files

0.7.6

2 files

0.7.5

2 files

0.7.3

2 files

0.7.2

2 files

0.7.1

2 files

0.7.0

2 files

0.6.2

2 files

0.6.1

2 files

0.6.0

2 files

0.5.3

2 files

0.5.2

2 files

0.5.1

2 files

0.5.0

2 files

0.4.1

2 files

0.4.0

2 files

0.3.0

2 files

0.2.2

2 files

0.2.1

2 files

0.2.0

2 files

0.1.1

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page