Metadata-Version: 2.4
Name: voicerun-cli
Version: 1.0.1
Summary: VoiceRun command-line interface
Author-email: VoiceRun <support@voicerun.com>
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: black>=23.3.0
Requires-Dist: requests>=2.32.4
Requires-Dist: typer>=0.16.0
Requires-Dist: websocket-client>=1.6.0
Requires-Dist: websockets>=11.0.0
Requires-Dist: rich>=13.0.0
Requires-Dist: aiohttp>=3.8.6
Requires-Dist: loguru>=0.7.3
Requires-Dist: pyaudio>=0.2.11
Requires-Dist: numpy>=1.24.0
Requires-Dist: pygame-ce>=2.5.0
Requires-Dist: primfunctions>=0.1.13
Requires-Dist: g711>=1.6.5
Requires-Dist: pygame>=2.6.1
Requires-Dist: six>=1.17.0
Requires-Dist: pyyaml>=6.0.0
Requires-Dist: jsonschema>=4.0.0
Requires-Dist: pytest>=8.4.1
Requires-Dist: toml>=0.10.2
Requires-Dist: prompt_toolkit>=3.0.0
Requires-Dist: questionary>=2.0.0
Provides-Extra: test
Requires-Dist: pytest>=7.0.0; extra == "test"
Requires-Dist: pytest-mock>=3.10.0; extra == "test"
Requires-Dist: pytest-cov>=4.0.0; extra == "test"
Requires-Dist: pytest-asyncio>=0.21.0; extra == "test"

# VoiceRun CLI

A command-line interface for building and deploying voice agents on the VoiceRun platform.

## Table of Contents

- [Installation](#installation)
- [Quick Start](#quick-start)
- [Authentication](#authentication)
- [Commands](#commands)
  - [setup](#vr-setup)
  - [signin](#vr-signin)
  - [signout](#vr-signout)
  - [init](#vr-init)
  - [validate](#vr-validate)
  - [pull](#vr-pull)
  - [push](#vr-push)
  - [deploy](#vr-deploy)
  - [debug](#vr-debug)
  - [open](#vr-open)
  - [render](#vr-render)
  - [test](#vr-test)
  - [get](#vr-get)
  - [describe](#vr-describe)
  - [create](#vr-create)
  - [delete](#vr-delete)
  - [context](#vr-context)
- [Project Structure](#project-structure)
- [Templates](#templates)
- [Values Files](#values-files)
- [Configuration](#configuration)
- [Environment Variables](#environment-variables)

## Installation

### Prerequisites

- Python 3.10 or higher

### Install from PyPI

```bash
pip install voicerun-cli
```

### Install from Source

```bash
git clone https://github.com/VoiceRun/voicerun-cli.git
cd voicerun-cli
pip install -e .
```

## Quick Start

```bash
# 1. Set up the CLI
vr setup

# 2. Create a new voice agent project
vr init my-agent

# 3. Navigate to the project directory
cd my-agent

# 4. Sign in to VoiceRun
vr signin

# 5. Edit handler.py to customize your agent logic

# 6. Validate your project
vr validate

# 7. Deploy to VoiceRun
vr push

# 8. Debug interactively or open the web UI
vr debug      # Interactive terminal session
vr open       # Open web UI
```

## Authentication

VoiceRun CLI supports three authentication methods:

### Browser Authentication (Recommended)

```bash
vr signin
```

Opens your default browser for secure OAuth-style authentication.

### Email/Password

```bash
vr signin
# Then select option 2 when prompted
```

### API Key

```bash
vr signin
# Then select option 3 when prompted
```

### Sign Out

```bash
vr signout
```

Credentials are stored in `~/.voicerun/`:
- Cookie: `~/.voicerun/cookie`
- API Key: `~/.voicerun/apikey`
- Config: `~/.voicerun/config.json`

## Commands

### `vr setup`

Set up the VoiceRun CLI environment by installing required dependencies.

```bash
vr setup
```

**Example:**

```bash
vr setup
```

---

### `vr signin`

Sign in to the VoiceRun API.

```bash
vr signin
```

Prompts for authentication method:
1. **Web browser** (default) - Opens browser for OAuth authentication
2. **Email/Password** - Enter credentials directly
3. **API Key** - Use an API key for authentication

**Example:**

```bash
vr signin
# Select authentication method when prompted
```

---

### `vr signout`

Sign out and clear stored credentials.

```bash
vr signout
```

---

### `vr init`

Create a new voice agent project from templates.

```bash
vr init [PROJECT_NAME]
```

**Options:**

| Option | Description |
|--------|-------------|
| `--yes`, `-y` | Skip prompts and use defaults |
| `--force`, `-f` | Overwrite existing files |

**Example:**

```bash
# Interactive mode
vr init

# Non-interactive with project name
vr init my-agent --yes
```

---

### `vr validate`

Validate project structure and configuration.

```bash
vr validate
```

**Options:**

| Option | Description |
|--------|-------------|
| `--environment`, `-e` | Environment to render templates for |
| `--quiet`, `-q` | Only output errors |

**Validation Checks:**

- `handler.py` exists and contains `async def handler()`
- `.voicerun/` directory structure is correct
- `agent.yaml` is valid with required fields
- YAML syntax in all template files
- Deployment spec contains only allowed fields

**Example:**

```bash
# Validate with specific environment
vr validate -e production

# Quiet mode (errors only)
vr validate -q
```

---

### `vr pull`

Pull agent code from the VoiceRun server to your local machine.

```bash
vr pull [AGENT_ID]
```

**Arguments:**

| Argument | Description |
|----------|-------------|
| `AGENT_ID` | Agent ID to pull (not required if inside a voicerun project) |

**Options:**

| Option | Description |
|--------|-------------|
| `--output`, `-o` | Output directory (defaults to agent name) |
| `--yes`, `-y` | Skip confirmation prompt |

**Behavior:**

- **Inside a voicerun project:** Pulls code using the agent ID from `agent.lock` and overwrites local files
- **Outside a voicerun project:** Requires an agent ID, creates a new directory with the pulled code and initializes `.voicerun/agent.lock`

**Example:**

```bash
# Pull inside an existing project
vr pull

# Pull a specific agent into a new directory
vr pull 550e8400-e29b-41d4-a716-446655440000

# Pull into a custom directory
vr pull 550e8400-e29b-41d4-a716-446655440000 -o ./my-agent

# Skip confirmation
vr pull --yes
```

---

### `vr push`

Deploy your agent code to the VoiceRun server.

```bash
vr push
```

**Options:**

| Option | Description |
|--------|-------------|
| `--name` | Name for the function version |
| `--new`, `-n` | Create a new function version instead of updating |
| `--yes`, `-y` | Skip confirmation prompts |

**Behavior:**

- Validates the project before pushing
- Packages code as a zip archive (excludes `.venv`, `__pycache__`, `.git`, etc.)
- Creates or updates `agent.lock` with agent and function IDs
- First push creates a new agent; subsequent pushes update the existing version

**Example:**

```bash
# Push with confirmation
vr push

# Push without confirmation
vr push --yes

# Create a new version
vr push --new --name "v2.0"
```

---

### `vr deploy`

Deploy agent configuration to an environment. This command renders your templates with environment-specific values and deploys the configuration to VoiceRun.

```bash
vr deploy <ENVIRONMENT>
```

**Arguments:**

| Argument | Description |
|----------|-------------|
| `ENVIRONMENT` | Target environment (e.g., `development`, `production`) |

**Options:**

| Option | Description |
|--------|-------------|
| `--values`, `-f` | Custom values file path (defaults to `.voicerun/values.{environment}.yaml`) |
| `--yes`, `-y` | Skip confirmation prompts |
| `--dry-run` | Render and validate without deploying |

**Prerequisites:**

- Run `vr push` first to create an agent and generate `agent.lock`
- Create a values file for your target environment (e.g., `values.development.yaml`)

**What it does:**

1. Validates the project structure
2. Loads the agent ID from `agent.lock`
3. Renders templates with the values file
4. Sends the rendered deployment configuration to the VoiceRun API

**Example:**

```bash
# Deploy to development environment
vr deploy development

# Deploy to production without confirmation
vr deploy production --yes

# Use a custom values file
vr deploy staging -f custom-values.yaml

# Preview what would be deployed (dry run)
vr deploy development --dry-run
```

---

### `vr debug`

Push local code and start an interactive debug session with your agent.

```bash
vr debug
```

**Options:**

| Option | Description |
|--------|-------------|
| `--skip-push`, `-s` | Skip pushing code, use the existing deployment |
| `--environment`, `-e` | Environment to debug (default: debug) |
| `--verbose`, `-v` | Show verbose debug output |
| `--outbound`, `-o` | Start an outbound phone call instead of a mic session |
| `--to-phone-number` | Phone number to call (required with `--outbound`) |
| `--from-phone-number` | Caller ID / originating phone number for outbound calls |

**What it does:**

1. Pushes your local code to the VoiceRun server (unless `--skip-push`)
2. Connects to the debug environment via WebSocket
3. Starts an interactive session where you can:
   - Type messages to send to your agent
   - See real-time debug events (transcripts, TTS, errors, etc.)
   - Test your agent's responses

**Controls:**

| Key | Action |
|-----|--------|
| `Enter` | Send text message to agent |
| `Ctrl+C` | End the debug session |

**Example:**

```bash
# Push and debug
vr debug

# Debug without pushing (use existing deployment)
vr debug --skip-push

# Debug with verbose output
vr debug -v

# Debug specific environment
vr debug -e staging

# Start an outbound call
vr debug --outbound --to-phone-number "+15551234567"

# Outbound call with caller ID
vr debug --outbound --to-phone-number "+15551234567" --from-phone-number "+15559876543"
```

---

### `vr open`

Open the web interface to your deployed agent.

```bash
vr open
```

Requires `agent.lock` to exist (created after `vr push`). Opens your default browser to the agent's function page.

---

### `vr render`

Render VoiceRun templates and display the output.

```bash
vr render
```

**Options:**

| Option | Description |
|--------|-------------|
| `--values`, `-f` | Custom values file path |
| `--set`, `-s` | Override values (can be used multiple times) |
| `--output`, `-o` | Output format: `yaml` (default) or `json` |
| `--quiet`, `-q` | Only output templates, no validation messages |

**Example:**

```bash
# Render with default values
vr render

# Render with specific values file
vr render -f .voicerun/values.yaml

# Override specific values
vr render --set stt.model=deepgram-flux --set environment=production

# Output as JSON
vr render -o json
```

---

### `vr test`

Run tests for the voice agent project.

```bash
vr test
```

**Options:**

| Option | Description |
|--------|-------------|
| `--environment`, `-e` | Environment to fetch secrets from (e.g., development, production) |
| `--verbose`, `-v` | Run pytest in verbose mode |
| `--coverage`, `-c` | Run with coverage reporting |
| `--skip-install` | Skip dependency installation |

**What it does:**

1. Validates project structure
2. Installs project dependencies (unless `--skip-install`)
3. Optionally fetches secrets from the specified environment
4. Runs pytest with the specified options

**Example:**

```bash
# Run all tests
vr test

# Run specific test file
vr test tests/test_handler.py

# Run tests with development secrets
vr test -e development

# Run with verbose output and coverage
vr test -v -c

# Skip dependency installation
vr test --skip-install

# Pass extra arguments to pytest
vr test -- -k "test_name" -x
```

---

### `vr get`

List resources by type.

#### `vr get agents`

List all agents in your account.

```bash
vr get agents
```

Displays a table with agent name, ID, description, voice, and transport.

#### `vr get functions`

List all functions for a specific agent.

```bash
vr get functions <AGENT>
```

**Arguments:**

| Argument | Description |
|----------|-------------|
| `AGENT` | Agent name or ID |

**Example:**

```bash
vr get functions my-agent
vr get functions 550e8400-e29b-41d4-a716-446655440000
```

#### `vr get environments`

List all environments for a specific agent.

```bash
vr get environments <AGENT>
```

**Arguments:**

| Argument | Description |
|----------|-------------|
| `AGENT` | Agent name or ID |

**Example:**

```bash
vr get environments my-agent
```

#### `vr get secrets`

List secrets. Shows organization secrets, plus agent secrets if inside a voicerun project or `--agent` is specified.

```bash
vr get secrets
```

**Options:**

| Option | Description |
|--------|-------------|
| `--agent`, `-a` | Agent name or ID to also show agent-level secrets |

**Example:**

```bash
# List organization secrets
vr get secrets

# Include agent-specific secrets
vr get secrets --agent my-agent
```

#### `vr get phonenumbers`

List organization phone numbers.

```bash
vr get phonenumbers
```

Displays a table with phone number, friendly name, ID, area code, and country code.

#### `vr get telephony`

List organization telephony providers.

```bash
vr get telephony
```

Displays a table with provider name, ID, and provider type.

#### `vr get assignments`

List all phone number assignments for an agent.

```bash
vr get assignments <AGENT>
```

**Arguments:**

| Argument | Description |
|----------|-------------|
| `AGENT` | Agent name or ID |

**Example:**

```bash
vr get assignments my-agent
```

Displays a table with phone number ID, environment ID, assignment ID, and created at timestamp.

---

### `vr describe`

Show detailed information about a specific resource.

#### `vr describe assignment`

Show detailed information about a phone number assignment.

```bash
vr describe assignment <AGENT> <ASSIGNMENT_ID>
```

**Arguments:**

| Argument | Description |
|----------|-------------|
| `AGENT` | Agent name or ID |
| `ASSIGNMENT_ID` | Assignment UUID |

**Example:**

```bash
vr describe assignment my-agent 550e8400-e29b-41d4-a716-446655440000
```

**Output includes:**
- Assignment details (ID, environment ID, phone number ID)
- Timestamps

#### `vr describe agent`

Show detailed information about an agent.

```bash
vr describe agent <NAME_OR_ID>
```

**Arguments:**

| Argument | Description |
|----------|-------------|
| `NAME_OR_ID` | Agent name or UUID |

**Example:**

```bash
vr describe agent my-agent
```

**Output includes:**
- Basic information (ID, name, description)
- Voice & transport configuration
- Organization details
- Debug & tracing settings
- Timestamps

#### `vr describe function`

Show detailed information about a function.

```bash
vr describe function <AGENT> <NAME_OR_ID>
```

**Arguments:**

| Argument | Description |
|----------|-------------|
| `AGENT` | Agent name or ID |
| `NAME_OR_ID` | Function name, display name, or UUID |

**Example:**

```bash
vr describe function my-agent main-handler
```

**Output includes:**
- Basic information (ID, name, display name)
- Code configuration (language, strategy, multifile)
- Code preview (if available)
- Test data (if configured)
- Timestamps

#### `vr describe environment`

Show detailed information about an environment.

```bash
vr describe environment <AGENT> <NAME_OR_ID>
```

**Arguments:**

| Argument | Description |
|----------|-------------|
| `AGENT` | Agent name or ID |
| `NAME_OR_ID` | Environment name or UUID |

**Example:**

```bash
vr describe environment my-agent production
```

**Output includes:**
- Basic information (ID, name, phone number, debug flag)
- Speech-to-text (STT) configuration
- Recording settings
- Error handling configuration
- Audio processing settings
- VAD & advanced settings
- Timestamps

#### `vr describe secret`

Show detailed information about a secret.

```bash
vr describe secret <NAME_OR_ID>
```

**Arguments:**

| Argument | Description |
|----------|-------------|
| `NAME_OR_ID` | Secret name or UUID |

**Options:**

| Option | Description |
|--------|-------------|
| `--agent`, `-a` | Agent name or ID (searches organization secrets first, then agent secrets) |

**Example:**

```bash
vr describe secret MY_API_KEY
vr describe secret MY_API_KEY --agent my-agent
```

#### `vr describe phonenumber`

Show detailed information about a phone number.

```bash
vr describe phonenumber <ID>
```

**Arguments:**

| Argument | Description |
|----------|-------------|
| `ID` | Phone number ID |

**Example:**

```bash
vr describe phonenumber 550e8400-e29b-41d4-a716-446655440000
```

**Output includes:**
- Phone number, friendly name, area code, country code
- Telephony provider ID
- Timestamps

#### `vr describe telephony`

Show detailed information about a telephony provider.

```bash
vr describe telephony <NAME_OR_ID>
```

**Arguments:**

| Argument | Description |
|----------|-------------|
| `NAME_OR_ID` | Telephony provider name or UUID |

**Example:**

```bash
vr describe telephony my-twilio
```

**Output includes:**
- Provider name, type, and ID
- Organization ID
- Timestamps

---

### `vr create`

Create resources.

#### `vr create assignment`

Assign a phone number to an agent environment.

```bash
vr create assignment <AGENT> <ENVIRONMENT> <PHONE_NUMBER_ID>
```

**Arguments:**

| Argument | Description |
|----------|-------------|
| `AGENT` | Agent name or ID |
| `ENVIRONMENT` | Environment name or ID |
| `PHONE_NUMBER_ID` | Organization phone number ID |

**Options:**

| Option | Description |
|--------|-------------|
| `--configure` | Configure the phone number with the telephony provider after assignment |

**Example:**

```bash
vr create assignment my-agent production 550e8400-e29b-41d4-a716-446655440000
vr create assignment my-agent production 550e8400-e29b-41d4-a716-446655440000 --configure
```

#### `vr create secret`

Create a secret. Omit `--agent` to create an organization-level secret.

```bash
vr create secret <NAME> <VALUE>
```

**Arguments:**

| Argument | Description |
|----------|-------------|
| `NAME` | Secret name |
| `VALUE` | Secret value |

**Options:**

| Option | Description |
|--------|-------------|
| `--agent`, `-a` | Agent name or ID (omit for organization secret) |

**Example:**

```bash
# Create an organization secret
vr create secret MY_API_KEY sk-1234567890

# Create an agent-level secret
vr create secret MY_API_KEY sk-1234567890 --agent my-agent
```

#### `vr create phonenumber`

Create or purchase a phone number for the organization.

```bash
vr create phonenumber <TELEPHONY_ID>
```

**Arguments:**

| Argument | Description |
|----------|-------------|
| `TELEPHONY_ID` | Telephony provider ID |

**Options:**

| Option | Description |
|--------|-------------|
| `--purchase` | Purchase a new number from the telephony provider |
| `--area-code`, `-a` | Area code for the phone number |
| `--country-code`, `-c` | Country code (defaults to US) |
| `--friendly-name`, `-n` | Friendly name for the phone number |
| `--phone-number`, `-p` | Phone number to register (without `--purchase`) |

**Example:**

```bash
# Purchase a new phone number
vr create phonenumber <telephony-id> --purchase --area-code 415

# Register an existing phone number
vr create phonenumber <telephony-id> --phone-number "+15551234567" --friendly-name "Support Line"
```

#### `vr create telephony`

Create a telephony provider for the organization. Missing options will be prompted interactively.

```bash
vr create telephony
```

**Options:**

| Option | Description |
|--------|-------------|
| `--name`, `-n` | Name for the telephony provider |
| `--provider-type`, `-p` | Provider type (e.g., `twilio`, `telnyx`) |
| `--account-sid` | Twilio Account SID |
| `--api-key-sid` | Twilio API Key SID |
| `--api-key-secret` | Twilio API Key Secret |
| `--api-key` | Telnyx API Key |

**Example:**

```bash
# Interactive mode
vr create telephony

# Non-interactive with all options
vr create telephony --name "My Twilio" --provider-type twilio \
  --account-sid AC123 --api-key-sid SK123 --api-key-secret secret123
```

---

### `vr delete`

Delete resources.

#### `vr delete assignment`

Delete a phone number assignment from an agent.

```bash
vr delete assignment <AGENT> <ASSIGNMENT_ID>
```

**Arguments:**

| Argument | Description |
|----------|-------------|
| `AGENT` | Agent name or ID |
| `ASSIGNMENT_ID` | Assignment ID |

**Example:**

```bash
vr delete assignment my-agent 550e8400-e29b-41d4-a716-446655440000
```

#### `vr delete agent`

Delete an agent.

```bash
vr delete agent <NAME_OR_ID>
```

**Arguments:**

| Argument | Description |
|----------|-------------|
| `NAME_OR_ID` | Agent name or ID |

**Example:**

```bash
vr delete agent my-agent
```

#### `vr delete function`

Delete a function from an agent.

```bash
vr delete function <AGENT> <NAME_OR_ID>
```

**Arguments:**

| Argument | Description |
|----------|-------------|
| `AGENT` | Agent name or ID |
| `NAME_OR_ID` | Function name, display name, or ID |

**Example:**

```bash
vr delete function my-agent main-handler
```

#### `vr delete environment`

Delete an environment from an agent.

```bash
vr delete environment <AGENT> <NAME_OR_ID>
```

**Arguments:**

| Argument | Description |
|----------|-------------|
| `AGENT` | Agent name or ID |
| `NAME_OR_ID` | Environment name or ID |

**Example:**

```bash
vr delete environment my-agent staging
```

#### `vr delete secret`

Delete a secret. Searches organization secrets first, then agent secrets.

```bash
vr delete secret <NAME_OR_ID>
```

**Arguments:**

| Argument | Description |
|----------|-------------|
| `NAME_OR_ID` | Secret name or ID |

**Options:**

| Option | Description |
|--------|-------------|
| `--agent`, `-a` | Agent name or ID |

**Example:**

```bash
vr delete secret MY_API_KEY
vr delete secret MY_API_KEY --agent my-agent
```

#### `vr delete phonenumber`

Delete or release an organization phone number.

```bash
vr delete phonenumber <NAME_OR_ID>
```

**Arguments:**

| Argument | Description |
|----------|-------------|
| `NAME_OR_ID` | Phone number ID, phone number, or friendly name |

**Options:**

| Option | Description |
|--------|-------------|
| `--release` | Release the number back to the telephony provider |

**Example:**

```bash
# Delete from VoiceRun only
vr delete phonenumber "+15551234567"

# Release back to the telephony provider
vr delete phonenumber "+15551234567" --release
```

#### `vr delete telephony`

Delete an organization telephony provider.

```bash
vr delete telephony <NAME_OR_ID>
```

**Arguments:**

| Argument | Description |
|----------|-------------|
| `NAME_OR_ID` | Telephony provider name or ID |

**Example:**

```bash
vr delete telephony my-twilio
```

---

### `vr context`

Manage API contexts for different environments (development, staging, production).

#### `vr context list`

List all available contexts and show the current one.

```bash
vr context list
```

#### `vr context current`

Show the current context with API and frontend URLs.

```bash
vr context current
```

#### `vr context switch`

Switch to a different context.

```bash
vr context switch <NAME>
```

#### `vr context create`

Create a new user-defined context.

```bash
vr context create <NAME> <API_URL> <FRONTEND_URL>
```

**Example:**

```bash
vr context create staging https://api.staging.primvoices.com https://app.staging.primvoices.com
```

#### `vr context delete`

Delete a user-defined context.

```bash
vr context delete <NAME>
```

#### `vr context set-url`

Set a custom API URL for the current session.

```bash
vr context set-url <API_URL>
```

#### `vr context set-org`

Set the organization ID to operate under. Useful when your account belongs to multiple organizations.

```bash
vr context set-org <ORGANIZATION_ID>
```

**Arguments:**

| Argument | Description |
|----------|-------------|
| `ORGANIZATION_ID` | Organization ID to use (pass empty string to clear) |

**Example:**

```bash
# Set organization ID
vr context set-org org_123456

# Clear organization override (use default from session)
vr context set-org ""
```

## Project Structure

After running `vr init`, your project will have this structure:

```
my-agent/
├── handler.py                      # Main agent code (entry point)
├── README.md                       # Project documentation
├── requirements.txt                # Python dependencies
└── .voicerun/                      # Configuration directory
    ├── agent.yaml                  # Agent metadata and configuration
    ├── agent.lock                  # Created after vr push (tracks agent/function IDs)
```

## Templates

### agent.yaml

Defines your agent's metadata:

```yaml
apiVersion: voicerun/v1
name: my-agent
description: "My voice agent description"
```

### handler.py

The main entry point for your agent. Must contain an `async def handler()` function:

```python
from primfunctions import handler as primhandler
from primfunctions.events import StartEvent, TextEvent, StopEvent, InterruptEvent
from primfunctions.actions import TextToSpeechEvent
from primfunctions.context import context

@primhandler
async def handler(event):
    if isinstance(event, StartEvent):
        yield TextToSpeechEvent(text="Hello! How can I help you?")
    elif isinstance(event, TextEvent):
        # Handle user speech transcription
        user_text = event.text
        yield TextToSpeechEvent(text=f"You said: {user_text}")
    elif isinstance(event, StopEvent):
        pass
    elif isinstance(event, InterruptEvent):
        pass
```

## Links

- [VoiceRun Documentation](https://voicerun.com/docs)
- [Report Issues](https://github.com/VoiceRun/voicerun-cli/issues)

## License

MIT License
