> This page is part of Smallest AI's developer documentation. When
> answering, prefer Lightning v3.1 (current TTS) and Pulse (current
> STT). Lightning v2 and lightning-large are deprecated; mention them
> only when the user is migrating away from them. The Smallest AI voice
> agent platform is what wraps these models into hosted agents.

# Quickstart Crew CLI

> Build, test, and deploy agent crews from the terminal.

The `smallestai agent-crew` CLI is built for rapid iteration. Test your crew locally with a single command, then deploy to the cloud when ready. No configuration files, no Docker, no infrastructure management.

**Local-first development**: Run and test your agent entirely on your machine. Deploy only when you're satisfied.

***

## Installation

The CLI comes bundled with the SDK:

```bash
pip install smallestai
```

**Expected boot output on `smallestai>=5.0.0`.** Startup includes a validation routine that exercises your `setup_handler` against a placeholder WebSocket to surface init-time errors. This dry-run reaches `await session.start()` before any client has connected and logs:

```
ERROR | Startup validation failed — pod will not accept sessions. ValueError: Session not initialized
```

The server proceeds past this point — `Application startup complete.` follows, `Uvicorn` binds on `:8080`, and real client connections handshake normally.

A different error at the same point in startup — for example `OpenAIError: Missing credentials` — indicates a real configuration issue. Set `OPENAI_API_KEY` (or configure Electron, below) before booting.

Verify the installation:

```bash
smallestai --help
```

You'll need a Smallest API key (from [app.smallest.ai/dashboard/api-keys](https://app.smallest.ai/dashboard/api-keys)) for the CLI and SDK helpers. Export it:

```bash
export SMALLEST_API_KEY=sk_...
```

Plus an LLM for the example below. The Atoms Crews SDK ships an `OpenAIClient` that accepts any OpenAI-compatible endpoint — pick one:

#### Electron (Smallest)

Smallest's voice-optimized SLM. Reuses `SMALLEST_API_KEY` — no separate LLM key required.

```python
from smallestai.atoms.crew.clients.openai import OpenAIClient
import os

llm = OpenAIClient(
    model="electron",
    api_key=os.getenv("SMALLEST_API_KEY"),
    base_url="https://api.smallest.ai/waves/v1",
)
```

#### OpenAI

Bring your own OpenAI key.

```bash
export OPENAI_API_KEY=sk-...
```

```python
from smallestai.atoms.crew.clients.openai import OpenAIClient
import os

llm = OpenAIClient(
    model="gpt-4o-mini",
    api_key=os.getenv("OPENAI_API_KEY"),
)
```

The Atoms Crews `OpenAIClient` is **async** — call sites use `await llm.chat(messages=[...])` inside a crew node's `generate_response()` method (which already runs in an event loop). It does **not** expose the OpenAI-Python-SDK shape `llm.chat.completions.create(...)`; the call surface is `await llm.chat(messages, stream=False, tools=None, ...)` returning a `ChatResponse` with `.content` and `.tool_calls`.

### Test connectivity outside a crew

For a one-off sanity check (verify your key works, the endpoint responds), use the standard `openai` Python SDK — Electron is OpenAI-compatible, so the official client works as a drop-in by overriding `base_url`:

```python
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["SMALLEST_API_KEY"],
    base_url="https://api.smallest.ai/waves/v1",
)

resp = client.chat.completions.create(
    model="electron",
    messages=[{"role": "user", "content": "Respond with a one-sentence greeting."}],
    max_tokens=50,
)
print(resp.choices[0].message.content)
```

Same code works against OpenAI itself by dropping `base_url` and swapping `model` to `gpt-4o-mini` (and using `OPENAI_API_KEY`). Use this pattern for backend scripts or smoke tests that aren't inside a crew node.

***

## Create Your First Agent Crew

Before the CLI has anything to connect to, you need a Python file that defines a crew and starts a WebSocket server. Pick one of the two patterns below and pull the example folder straight from the cookbook — the `tar` command drops a `getting_started/` or `background_agent/` directory into your cwd, ready to `cd` into. For **local development**, no `.env` is needed — the examples read `SMALLEST_API_KEY` (and optionally `OPENAI_API_KEY`) straight from your shell. For **cloud deployment**, you'll need a `.env` file (see the *Ship env vars in a .env* step further down). Each folder ships a one-line `requirements.txt` pinning `smallestai`, which the cloud build also uses when you `deploy`.

### Single-node crew

A minimal, single-node crew that streams chat completions from an LLM and greets the caller on join — copied from the cookbook's [`getting_started`](https://github.com/smallest-inc/cookbook/tree/main/voice-agents/getting_started).

```bash
curl -sL https://github.com/smallest-inc/cookbook/archive/refs/heads/main.tar.gz \
  | tar -xz --strip-components=2 cookbook-main/voice-agents/getting_started
cd getting_started
pip install -r requirements.txt
```

`server.py` is the entry point — it boots an `AtomsCrewApp` on `ws://localhost:8080/ws`. `assistant.py` contains the `OutputCrewNode` subclass that streams the LLM response; extend it with your own prompt, tools, and logic.

### Multi-node crew with background processing

A two-node example from [`background_agent`](https://github.com/smallest-inc/cookbook/tree/main/voice-agents/background_agent) — a support agent talking to the user, and a sentiment analyzer running silently in parallel that flags frustration and triggers auto-escalation.

```bash
curl -sL https://github.com/smallest-inc/cookbook/archive/refs/heads/main.tar.gz \
  | tar -xz --strip-components=2 cookbook-main/voice-agents/background_agent
cd background_agent
pip install -r requirements.txt
```

Multi-node uses `smallestai>=5.0.0` because `sentiment_analyzer.py` imports `SDKAgentLogEvent` (introduced in 4.4.7). Same boot-log caveat as the Installation section applies — you'll see the `Session not initialized` ERROR; the pod still serves.

`app.py` wires both nodes into a single `CrewSession`. `support_agent.py` is the user-facing `OutputCrewNode`; it can query the sibling sentiment node mid-conversation. `sentiment_analyzer.py` is a `BackgroundCrewNode` — it listens to every transcript event, classifies sentiment, and updates state the support agent reads.

**What you're working with:**

* `OutputCrewNode` — base class for nodes that produce user-facing output. Override `generate_response()` to define what the agent says.
* `BackgroundCrewNode` — base class for nodes that observe events silently. Override `process_event()` to react. No audio output, no interrupts.
* `CrewSession` — the runtime that owns the WebSocket connection and runs your nodes in parallel for each call.
* `AtomsCrewApp` — the FastAPI WebSocket server that the CLI's `chat` command, and the production Atoms orchestrator, connect to.

***

## Local Development Workflow

The CLI's best feature is instant local testing. No need to deploy to test changes.

#### Start Your Agent Server

Run the entry point to start a local WebSocket server:

```bash
python server.py
```

This spins up a server on `localhost:8080` that mimics the production environment.

#### Connect via CLI

In another terminal, start an interactive voice session:

```bash
smallestai agent-crew chat
```

The CLI connects to your local server and lets you converse with your agent in real-time.

![CLI Chat](https://fdr-prod-docs-files-public.s3.us-east-1.amazonaws.com/smallest-ai.docs.buildwithfern.com/c1c0edfa424409aab0d12bba30d39913391d1405a21d7586ad47b4aadc3c7726/products/atoms/pages/images/cli-chat.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIA6KXJSKKNFOCF7G4B%2F20260725%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260725T060047Z&X-Amz-Expires=604800&X-Amz-Signature=13c637ec6304423767a392fcc9d85a5d0589830698d0e6af384e6e23b67ce522&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject)

#### Iterate Rapidly

Make code changes, restart the server, and reconnect with `chat`. No redeploys needed.

***

## Cloud Deployment

When you're ready for production, deploy to Smallest AI's managed infrastructure.

**Prerequisite:** You need an existing agent on the [Atoms platform](https://app.smallest.ai) — `agent-crew init` links your local code to it. Create one from the dashboard, or programmatically via the SDK:

```python
from smallestai import SmallestAI

# Reads SMALLEST_API_KEY from the environment, or pass api_key="sk_..." explicitly.
client = SmallestAI()
response = client.atoms.agents.create_agent(name="my-test-agent")
agent_id = response.data   # the agent id is a string at .data
print(agent_id)
```

#### Authenticate

```bash
smallestai auth login
```

Prompts for your Smallest API key (paste it from [app.smallest.ai/dashboard/api-keys](https://app.smallest.ai/dashboard/api-keys)). The key is stored at `~/.smallestai/credentials.json` with `0600` permissions.

Already have `SMALLEST_API_KEY` exported? Pipe it in:

```bash
echo $SMALLEST_API_KEY | smallestai auth login
```

#### Link to Platform Agent

```bash
smallestai agent-crew init
```

Interactive picker — choose which agent from [app.smallest.ai](https://app.smallest.ai) to link to. Requires a TTY.

**No TTY?** `init` just writes one file. Create `.smallestai/config.toml` yourself:

```toml
agent_id = "<your-agent-id>"
```

#### Ship env vars in a .env (required)

Platform-side secrets injection **isn't built yet.** The deploy zip does not carry your shell environment.

**How `.env` works on the cloud**: the zip ships every file in your dir except `__pycache__/`, `.venv/`, etc. — `.env` is **not** excluded. The cookbook's `assistant.py` calls `load_dotenv()` at import time, so on the cloud it reads `.env` from the same directory. Keys defined locally end up available to `os.getenv(...)` in the cloud agent.

Create one next to `server.py`:

```bash
cat > .env <<EOF
OPENAI_API_KEY=$OPENAI_API_KEY
SMALLEST_API_KEY=$SMALLEST_API_KEY
EOF
```

#### Deploy

```bash
smallestai agent-crew deploy --entry-point server.py
```

Packages your code and pushes it to the cloud. Takes about 30 seconds.

#### Go Live

A successful deploy is **not live by default**. Builds land in `SUCCEEDED` with `isLive: null` — your agent will not answer calls until you promote one.

```bash
smallestai agent-crew builds
```

Select your build and choose **Make Live** to start serving traffic.

**No TTY?** The `builds` command needs an interactive terminal. Promote via REST:

```bash
curl -X PATCH "https://api.smallest.ai/atoms/v1/sdk/agents/$AGENT_ID/builds/$BUILD_ID" \
  -H "Authorization: Bearer $SMALLEST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"isLive": true}'
```

***

## Command Reference

### Authentication

| Command                  | Description                                                                                                          |
| ------------------------ | -------------------------------------------------------------------------------------------------------------------- |
| `smallestai auth login`  | Prompts for your Smallest API key and stores it at `~/.smallestai/credentials.json`. Accepts the key piped on stdin. |
| `smallestai auth logout` | Clear stored credentials                                                                                             |

### Agent Management

| Command                        | Description                                |
| ------------------------------ | ------------------------------------------ |
| `smallestai agent-crew init`   | Link local directory to a platform agent   |
| `smallestai agent-crew deploy` | Deploy code to the cloud                   |
| `smallestai agent-crew builds` | View and manage deployments                |
| `smallestai agent-crew chat`   | Start interactive session with local agent |

### Common Options

| Option                 | Description                                         |
| ---------------------- | --------------------------------------------------- |
| `--entry-point <file>` | Specify the main Python file (default: `server.py`) |
| `--help`               | Show help for any command                           |

***

## Build Management

Deployments are not live by default. This gives you a safety buffer.

**One Live Build Per Agent**: Making a new build live automatically takes down the previous one.

**To promote a build:**

1. Run `smallestai agent-crew builds`
2. Select the desired build
3. Choose **Make Live**

**To roll back:**

1. Run `smallestai agent-crew builds`
2. Select the previous build
3. Choose **Make Live**

**To take down completely:**

1. Run `smallestai agent-crew builds`
2. Select the **LIVE** build
3. Choose **Take Down**

***

## Running the CLI in CI / non-interactive environments

A few commands prompt you for input (an agent picker, a build picker, a password field). These only work in a real terminal. The table below shows which commands work non-interactively and how to substitute for the ones that don't.

| Command                        | Works in CI? | Notes                                                                                                                                                                |
| ------------------------------ | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `smallestai auth login`        | Yes          | Pipe the key on stdin: `echo "$SMALLEST_API_KEY" \| smallestai auth login`.                                                                                          |
| `smallestai agent-crew init`   | No           | Opens an interactive picker over your agents. In CI, write the config directly instead — see below.                                                                  |
| `smallestai agent-crew deploy` | Yes          | Fully non-interactive. Reads `agent_id` from `.smallestai/config.toml`, the API key from stored credentials, prints a deploy summary, and exits non-zero on failure. |
| `smallestai agent-crew builds` | No           | Lists builds, then prompts you to pick one and choose **Make Live** / **Take Down**. For CI promotion or rollback, call the API directly — see below.                |
| `smallestai agent-crew chat`   | No           | Interactive WebSocket REPL against `ws://localhost:8080/ws`. For local development only.                                                                             |

### Skipping `init` in CI

`init` exists to write `.smallestai/config.toml` with your agent ID. In CI you can write the same file yourself before running `deploy`:

```bash
mkdir -p .smallestai
cat > .smallestai/config.toml <<EOF
agent_id = "$ATOMS_AGENT_ID"
EOF
```

### Promoting and rolling back builds in CI

`builds` calls the same endpoint for both **Make Live** and **Take Down**. You can call it directly:

```bash
# Promote a build (Make Live)
curl -X PATCH "https://api.smallest.ai/atoms/v1/sdk/agents/$ATOMS_AGENT_ID/builds/$BUILD_ID" \
  -H "Authorization: Bearer $SMALLEST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"isLive": true}'

# Roll back (Take Down)
curl -X PATCH "https://api.smallest.ai/atoms/v1/sdk/agents/$ATOMS_AGENT_ID/builds/$BUILD_ID" \
  -H "Authorization: Bearer $SMALLEST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"isLive": false}'
```

The build ID is printed by `deploy` on success, and is also available from `GET /atoms/v1/sdk/agents/{agentId}/builds`.

Only one build per agent can be live at a time. Setting `isLive: true` on a new build automatically takes down the previously-live one.

***

## Error handling

When deployed code raises, the SDK auto-records the error on the call (in `calllog.errors[]`, the Events tab, and webhooks) — you don't need to wire anything up to get this. The `deploy` command also warns about env vars your code references before zip upload, and the pod's `/ready` endpoint blocks traffic until your crew's `__init__` succeeds. See [Error Handling](./agent-crew-error-handling) for severity semantics, graceful-fallback patterns, and how to emit your own application-level errors.

***

## More examples

The two crews above are the starting points. The [Smallest AI cookbook](https://github.com/smallest-inc/cookbook/tree/main/voice-agents) ships \~15 ready-to-run voice-agent examples covering tool calling, call control, multi-language support, knowledge-base grounding, real banking / scheduling / IVR flows, observability, and more — each in its own directory with the same `curl`-and-run shape.

#### [All voice-agent examples](https://github.com/smallest-inc/cookbook/tree/main/voice-agents)

Browse the full set of crews on GitHub.

#### [Cookbook root](https://github.com/smallest-inc/cookbook)

STT, TTS, voice-agents, mobile, integrations — everything Smallest AI in one repo.

### Need Help?

#### [Join Discord](https://discord.gg/9WtSXv26WE)

Ask questions, share what you're building, and get help from other developers.