# CLI

OpenRTC ships a console script named `openrtc` (Typer + Rich) for discovery-based
workflows. The Typer application and `main()` live in `openrtc.cli.commands` (with
helpers in `openrtc.cli.livekit`, `openrtc.cli.dashboard`, `openrtc.cli.reporter`,
`openrtc.cli.types`, and `openrtc.cli.params`). The lazy entrypoint and missing-extra
hints are in `openrtc.cli` (the package `__init__` plus `openrtc.cli.entry`).
The programmatic entry is `typer.main.get_command(app).main(...)` (Click’s
`Command.main`), not the test-only `CliRunner`.

## Installation

The **library** (`AgentPool`, discovery, routing) installs with:

```bash
pip install openrtc
```

The **CLI stack** (Typer, Rich) is the optional extra `cli`:

```bash
pip install 'openrtc[cli]'
```

If Typer/Rich are not importable, `openrtc.cli:main` exits with `1` and prints
an install hint.

## Typical usage

1. Set the same variables as a standard LiveKit worker:

   ```bash
   export LIVEKIT_URL=ws://localhost:7880
   export LIVEKIT_API_KEY=devkey
   export LIVEKIT_API_SECRET=secret
   ```

2. Run a worker subcommand with an agents directory (plus any provider defaults
   your agents need). You can pass **`--agents-dir`** or use the **first
   positional argument** on ``start`` / ``dev`` / ``console``. A **second**
   positional is **optional** and only sets ``--metrics-jsonl`` when you want JSONL
   metrics; skip it if you only need the agents directory (unless you already
   passed ``--metrics-jsonl``).

   ```bash
   openrtc dev ./agents
   openrtc dev ./agents ./openrtc-metrics.jsonl
   # equivalent to:
   openrtc dev --agents-dir ./agents --metrics-jsonl ./openrtc-metrics.jsonl
   openrtc start --agents-dir ./agents
   ```

Defaults are conservative: **no** Rich dashboard unless you pass `--dashboard`,
and **no** metrics files unless you pass `--metrics-json-file` or
`--metrics-jsonl`. Refresh intervals default to **1 second** where applicable.

Subcommands mirror the LiveKit Agents CLI (`python agent.py dev`, `start`,
`console`, `connect`, `download-files`). OpenRTC adds **`--agents-dir`** for
discovery, then delegates to `livekit.agents.cli.run_app`. OpenRTC-only flags are
stripped from `sys.argv` before that handoff so LiveKit does not see options
like `--agents-dir`.

## Connection overrides

You can override `LIVEKIT_*` per invocation:

- `--url`
- `--api-key`
- `--api-secret`
- `--log-level` (also `LIVEKIT_LOG_LEVEL`)

These appear under **Connection** or **Advanced** in `--help` depending on the
flag.

## Commands

Across **list**, **connect**, **download-files**, and
**start** / **dev** / **console**, you can often pass paths **positionally**
instead of `--agents-dir` or `--metrics-jsonl` (see each command below). The
first non-flag token after the subcommand is rewritten before parsing; use
`--agents-dir` when you need a different argument order.

### `openrtc list`

Discovers agent modules and prints each agent’s resolved settings.

- **Default:** Rich **table** (human-friendly).
- **`--plain`** — Stable, line-oriented text (no ANSI/table borders); good for
  grep and CI.
- **`--json`** — Stable JSON. Top-level fields include `schema_version` (bump
  when the shape changes) and `command: "list"`. Combine with `--resources` for
  `resource_summary`.
- **`--plain` and `--json` together** are rejected (non-zero exit).
- **`--resources`** — Footprint and memory hints (grouped under **Advanced** in
  `--help`).

```bash
openrtc list ./agents
openrtc list --agents-dir ./agents --plain
openrtc list ./agents --json
```

### `openrtc start` / `openrtc dev` / `openrtc console`

Worker subcommands. `start` is production-style; `dev` adds reload;
`console` is a local-only sandbox. All three accept the same option
shape (see `--help` per command for the full list).

```bash
openrtc start ./agents
openrtc dev ./agents
openrtc console ./agents
```

#### Coroutine-mode runtime knobs (v0.1)

Two flags pick the worker isolation mode and the coroutine-mode
backpressure threshold. They show up under the **OpenRTC** panel in
`--help` and are accepted by `start`, `dev`, and `console`.

- **`--isolation`** — `coroutine` (default) or `process`.
  - `coroutine` runs every session as an `asyncio.Task` inside one
    worker process and shares the prewarmed VAD / turn detector
    across sessions. Use this when density is the goal.
  - `process` keeps the v0.0.x behavior of one OS subprocess per
    session via `livekit-agents`'s default `ProcPool`. Use this when
    you need hard process isolation between sessions or per-session
    memory caps via `livekit-agents`' `job_memory_limit_mb`.
- **`--max-concurrent-sessions`** — Integer ≥ 1, default `50`. The
  coroutine pool reports `load >= 1.0` to LiveKit dispatch once this
  many sessions are in flight, so the dispatcher routes new jobs
  elsewhere. Ignored under `--isolation process` (livekit-agents'
  own load math applies there).

```bash
# Default: coroutine mode at 50 concurrent sessions per worker.
openrtc start ./agents

# Opt back into v0.0.x behavior:
openrtc start ./agents --isolation process

# Tune the coroutine threshold for a 1-vCPU / small-memory host:
openrtc start ./agents --max-concurrent-sessions 12
```

See `docs/concepts/architecture.md` for the coroutine-mode lifecycle
and the README's "Isolation modes" section for a side-by-side
comparison table.

### `openrtc connect`

Connect the worker to an existing room (LiveKit `connect`). Requires
`--room`.

```bash
openrtc connect ./agents --room my-room
```

### `openrtc download-files`

Download plugin assets (LiveKit `download-files`). Only needs the agents
directory (for a valid worker entrypoint) plus connection settings—**no**
`--default-stt` / `--default-llm` / `--default-tts` / `--default-greeting`.

```bash
openrtc download-files ./agents
```

## Runtime visibility and automation

- **`--dashboard`** — Live Rich summary (RSS, sessions, routing, savings
  estimate). Off by default.
- **`--metrics-json-file PATH`** — Overwrites a JSON file each tick with the
  latest `PoolRuntimeSnapshot` (good for scripts). Grouped under **Advanced**.
- **`--metrics-jsonl PATH`** — Appends **versioned JSON Lines** (truncates when
  the worker starts). Each line is one record: `schema_version`, `kind`
  (`snapshot` or `event`), `seq`, `wall_time_unix`, `payload`. Snapshots match
  `PoolRuntimeSnapshot.to_dict()`; events carry session lifecycle hints
  (`session_started`, `session_finished`, `session_failed`). Tail it with
  `tail -f ./openrtc-metrics.jsonl`, pipe it through `jq`, or point any log
  shipper or script at it.
- **`--dashboard-refresh`** — Interval in seconds for dashboard, metrics file,
  and JSONL when `--metrics-jsonl-interval` is not set (**Advanced**).
- **`--metrics-jsonl-interval`** — Override JSONL cadence only (**Advanced**).

## Shared default options (discovery)

Worker commands that load agents accept optional defaults applied when a
discovered agent does not override them via `@agent_config(...)`:

- `--default-stt`
- `--default-llm`
- `--default-tts`
- `--default-greeting` (**Advanced**)

Example:

```bash
openrtc list \
  --agents-dir ./examples/agents \
  --default-stt openai/gpt-4o-mini-transcribe \
  --default-llm openai/gpt-4.1-mini \
  --default-tts openai/gpt-4o-mini-tts
```

These defaults are passed through to `livekit-agents` as raw strings. For
provider-native plugin objects, configure them in Python with `AgentPool`
instead of through the CLI flags.

## `list --resources` (footprint)

With **`--resources`**, `list` adds:

- **Per-agent** on-disk size of the discovered `.py` module when the path is
  known (see `AgentConfig.source_path` in the API docs).
- **Summary** — total source bytes and a **best-effort** process memory metric
  from `openrtc.observability.metrics` (Linux: current VmRSS; macOS: peak
  `ru_maxrss`, not live RSS—see `resident_set.description` in `--json` output).
- **Savings estimate** — a transparent estimate of the memory saved by one
  shared worker versus one worker per registered agent.

```bash
openrtc list --agents-dir ./examples/agents --resources
openrtc list --agents-dir ./examples/agents --resources --json
```

## Notes

- `--agents-dir` is required for every command.
- `list` returns a non-zero exit code when no discoverable agents are found.
- Worker commands discover agents before handing off to the LiveKit CLI.
- The live dashboard, `--metrics-json-file`, and `--metrics-jsonl` reflect the
  **running** shared worker, unlike `list --resources`, which reflects the
  short-lived CLI discovery process.

## Prove the shared-worker value locally

1. Discover your agents:

   ```bash
   openrtc list --agents-dir ./examples/agents --resources
   ```

2. Start one shared worker with the dashboard and/or metrics output:

   ```bash
   openrtc dev \
     --agents-dir ./examples/agents \
     --dashboard \
     --metrics-json-file ./runtime.json
   ```

   Or enable a streaming JSON Lines feed:

   ```bash
   openrtc dev \
     --agents-dir ./examples/agents \
     --metrics-jsonl ./openrtc-metrics.jsonl
   ```

3. Watch the dashboard (or tail the JSONL file with
   `tail -f ./openrtc-metrics.jsonl`, optionally piped through `jq`) for
   worker RSS, active sessions, routing, and errors.

4. Use `runtime.json` or the JSONL stream for automation or scraping.

For production capacity planning, compare these snapshots with host or container
telemetry from your deployment platform.
