Metadata-Version: 2.4
Name: vocal-bridge
Version: 0.27.0
Summary: CLI tools for Vocal Bridge voice agent development
License-Expression: Apache-2.0
Project-URL: Homepage, https://vocalbridgeai.com
Project-URL: Documentation, https://vocalbridgeai.com/docs/developer-guide
Keywords: voice,agent,ai,cli,vocal-bridge
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Communications :: Telephony
Classifier: Topic :: Multimedia :: Sound/Audio :: Speech
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: websockets>=16.0; python_version >= "3.10"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: build; extra == "dev"
Requires-Dist: twine; extra == "dev"
Dynamic: license-file

# Vocal Bridge CLI

Developer tools for iterating on voice agents built with [Vocal Bridge](https://vocalbridgeai.com).

## Installation

```bash
pip install vocal-bridge
```

Requires Python 3.9+. Real-time debug streaming uses WebSockets on Python 3.10+
and automatically falls back to HTTP polling on Python 3.9.

## Quick Start

```bash
# Authenticate with your API key (get this from the Vocal Bridge dashboard)
vb auth login

# View your agent info
vb agent

# View recent call logs
vb logs

# View call statistics
vb stats

# Update your agent's prompt
vb prompt edit
```

## Release 0.27.0

Version 0.27.0 adds explicit per-environment undeploy across the CLI, dashboard,
and API. Undeploy stops new sessions in the selected environment without deleting
the agent or its immutable versions. Production talk links stop routing until a
version is deployed again; configuration-sharing settings remain available.

```bash
python -m pip install --upgrade vocal-bridge==0.27.0
vb --version
vb agent environment undeploy production
```

## Release 0.26.0

Version 0.26.0 adds enterprise agent version management to the CLI: immutable
save history, labels and audit notes, secret-safe save/deploy diffs, named
environments, optimistic concurrency checks, and independent deployment of the
same version to multiple test or production stages. Existing commands continue
to target the `production` environment by default.

```bash
python -m pip install --upgrade vocal-bridge==0.26.0
vb --version
```

## Authentication

### API Key Types

Vocal Bridge supports two types of API keys:

- **Agent API keys**: Tied to a specific agent. Get one from your agent's detail page.
- **Account API keys**: Work across all your agents. Create one from the dashboard's "API Keys" tab. After login, use `vb agent use` to select which agent to work with. When calling the API directly with an account key, include the `X-Agent-Id` header with the agent UUID.

### Login with API Key

```bash
# Interactive login
vb auth login

# Or provide key directly
vb auth login vb_your_api_key_here

# For account keys, select an agent after login
vb agent use
```

### Check Status

```bash
vb auth status
```

### Logout

```bash
vb auth logout
```

### Environment Variables

You can also set credentials via environment variables:

```bash
export VOCAL_BRIDGE_API_KEY=vb_your_api_key_here
export VOCAL_BRIDGE_API_URL=https://vocalbridgeai.com  # optional
```

## Commands

### Agent Info

```bash
# Show current agent details
vb agent

# List all agents
vb agent list

# Select an agent to work with (interactive)
vb agent use

# Select by agent ID or name
vb agent use <agent_id>
vb agent use "Whiskers the Math Cat"
```

### Create Agent (Paid Subscribers)

Create and deploy a new voice agent programmatically. Requires an active paid subscription. Maximum 50 agents per account.

```bash
# Create a simple chatty agent
vb agent create --name "My Assistant" --style Chatty --prompt "You are a helpful assistant."

# Create with a greeting
vb agent create --name "Sales Bot" --style Focused \
  --prompt "You help customers find products." \
  --greeting "Hi! How can I help you today?"

# Create web-only agent (no phone number)
vb agent create --name "Web Agent" --style Chatty \
  --prompt "You are a support agent." --deploy-targets web

# Create from a prompt file
vb agent create --name "Custom Agent" --style Focused --prompt-file prompt.txt

# Create with model settings
vb agent create --name "Custom Voice" --style Focused \
  --prompt "You are helpful." --model-settings-file settings.json

# Create with MCP server integrations
vb agent create --name "Connected Agent" --style Chatty \
  --prompt "You help with scheduling." --mcp-servers-file servers.json

# Create a Listener agent (passive observer, never speaks — streams transcripts
# and coaching suggestions to your app via the data channel)
vb agent create --name "IR Coach" --style Listener \
  --prompt "You coach during earnings Q&A. Trigger on analyst questions. Respond with a bold recommended answer, 2-3 supporting bullets, and one italic caveat." \
  --coachee-description "the company CFO during earnings Q&A" \
  --coaching-debounce 8

# Output as JSON
vb agent create --name "Test" --style Chatty --prompt "Hello." --json
```

Suggestion: when setting a greeting, consider identifying the agent and company and including any disclosure, consent, or recording language your laws, regulations, or policies require.

**Required flags:**
- `--name` — Agent name
- `--style` (or `--mode`) — Agent style: Chatty, Focused, Gemini, Ultravox, or Listener
- `--prompt` or `--prompt-file` — System prompt (text or file path)

**Optional flags:**
- `--greeting` — Greeting message. Suggestion: identify the agent/company and include any disclosure, consent, or recording language your laws, regulations, or policies require.
- `--deploy-targets` — `phone`, `web`, or `both` (default: `both`)
- `--background-enabled` — Enable background AI: `true`/`false` (default: `true`)
- `--web-search-enabled` — Enable web search: `true`/`false` (default: `true`)
- `--hold-enabled` — Enable hold: `true`/`false` (default: `false`)
- `--transfer-enabled` — Enable cold and warm call transfers: `true`/`false` (default: `false`)
- `--transfer-destination` — Approved E.164 number or SIP URI; repeat for each allowed destination
- `--hangup-enabled` — Enable hangup: `true`/`false` (default: `false`)
- `--debug-mode` — Enable debug mode: `true`/`false` (default: `false`)
- `--background-model` — Claude model for background AI jobs: `auto`, `claude-haiku-4-5`, or `claude-sonnet-4-6` (default: `auto`)
- `--post-processing-model` — Model for post-call processing: `auto`, `gemini-3.5-flash`, `gemini-2.5-flash`, or `gemini-2.5-flash-lite` (default: `auto`)
- `--model-settings-file` — JSON file with model settings
- `--mcp-servers-file` — JSON file with MCP servers array
- `--client-actions-file` — JSON file with client actions array
- `--api-tools-file` — JSON file with custom HTTP API tools array. Per-tool `capture_evidence` defaults to `false`; enable it for bounded, secret-redacted Eval input/output assertions. Configured URLs, headers, and auth are excluded from evidence.
- `--ai-agent-file` — JSON file with AI Agent integration config
- `--ai-agent-enabled`, `--ai-agent-description`, `--ai-agent-verbatim`, `--ai-agent-url`, `--ai-agent-header`, `--ai-agent-param`, `--ai-agent-protocol`, `--ai-agent-a2a-method`, `--ai-agent-response-mode`, `--ai-agent-response-ordering`, `--ai-agent-late-responses`, `--ai-agent-duplicate-responses`, `--ai-agent-max-responses-per-turn`, `--ai-agent-max-chars-per-turn` — Inline AI Agent integration settings
- `--json` — Output result as JSON

### Delete Agent

Permanently delete an agent and release its phone number. Requires typing the agent name to confirm.

```bash
# Delete the currently selected agent (interactive confirmation)
vb agent delete

# Delete a specific agent by ID
vb agent delete <agent_id>

# Skip confirmation prompt (use with caution)
vb agent delete --force

# Output as JSON
vb agent delete --json
```

The delete command will:
1. Show agent details and ask you to type the agent name to confirm
2. Delete the dispatch rule and release the phone number
3. Remove the agent from your account

If the deleted agent was your currently selected agent, the selection is cleared automatically.

### Agent Versions and Environments

Vocal Bridge manages platform updates; you manage your agents through the dashboard, CLI, or API. Existing agents keep working without any setup changes.

#### Security and ownership hand-off

API keys are revoked on ownership transfer. The recipient must mint fresh
agent-scoped keys and run `vb auth login` again with the replacement credential.
Untransferred agents, account keys, saves/deploys/rollbacks, and same-owner updates
keep their existing keys. Failed transfers roll back revocation. Already-issued
connection tokens and active calls are not cancelled. The former owner remains an Admin
collaborator under the existing contract; the recipient must remove that access
separately for a clean hand-off and review other collaborators/shared links/grants.

Creation and transfer share the same logical-agent limit (plan plus partner agent slots), separate from phone-environment capacity. Versions and environments remain one logical agent. If concurrent requests compete for the final slot, one returns **403** without creating or transferring an agent. Pending and failed non-deleted agents count; deleted agents do not. Existing over-limit agents and deployed versions remain unchanged.

Only the current owner can accept new outbound terms. Edit/Admin collaborators, including a former owner retained as Admin, cannot record `outbound_tos_accepted: true` on the owner's behalf: fresh attempts return **403** before saving. This restriction also applies if ownership changes during the request. Existing owner consent remains valid: older dashboards echoing `true` can keep editing, without replacing the first acceptance timestamp. Ordinary collaborator saves without new acceptance remain supported. Legacy API/classic edits enforce the same ownership checks. Consent is shared agent policy, not version configuration.

CLI 0.26.0 masks known secret paths in version responses and escapes terminal
controls, including labels, environment names and diff paths. Export and diff
responses also redact recognized credential fields. Keep labels/prompts free of
secrets and exports private. Redaction
does not remove secrets from older downloads or revoke credentials. Rotate exposed
credentials, then save and deploy a new configuration; version history is immutable.

`POST /api/v1/token` requires an API key. A named `environment` also requires a
matching `X-Agent-Environment` header so a body-forwarding token proxy cannot
silently expose another deployment. Customer proxies must still authorize callers
and choose their own fixed environment. Public shared links stay production-only.
Environments are not separate permission boundaries. Version requests are rate
limited; handle 429 responses with backoff and obtain fresh state before retrying.

Saving and deploying are separate operations in CLI **0.26.0+**. A save records an
immutable, labelable configuration snapshot and updates the editable config; it
does not change any environment's deployed version. Deploy changes only the
selected environment, not the editable config. A no-change save can reuse the
latest snapshot (`created: false`); use the returned version ID/number.

The [developer guide](https://vocalbridgeai.com/docs/overview#agent-versioning)
includes the public API reference, concurrency-safe backend examples, and SDK
token integration. Get the same detailed guidance in your terminal with
`vb docs` (or `vb docs --json`), backed by `GET /api/v1/docs`.

**Compatibility:** `vb prompt set/edit`, `vb config set/edit`, and legacy
`PATCH /api/v1/agent` still save and deploy to production. Do not use those
commands to prepare staged-only changes; write the changes to a config file and
use `vb agent version save` instead.

After an explicit web-only deployment retires production's phone resources,
`vb config set --deploy-targets phone` (or `both`) provisions the missing
phone/dispatch before publishing production. Current owner entitlement and shared
phone capacity, including partner slots, apply; denial returns **403**. A retired
number is not guaranteed to return. Existing phone resources are reused when
present; named environments are unchanged. A failed deployment can leave the new
snapshot saved while production stays on its prior version. Inspect history
before retrying after a timeout; concurrent changes require refresh/retry.
Deployment prerequisites are checked before allocation. Ordinary edits to
an already complete phone deployment do not buy another number.

For example, create `candidate.json`:

```json
{
  "greeting": "Hello from the release candidate.",
  "custom_prompt": "You are a helpful support assistant.",
  "deploy_targets": "web"
}
```

```bash
# Inspect history and current environment pointers
vb agent version list
vb agent environment list

# Save the current dashboard/legacy draft as a version
vb agent version save --label release-candidate

# Save a partial or full JSON configuration as a new version
vb agent version save --config-file candidate.json \
  --label rc-2 --description "Passed regression suite"

# Compare immutable versions by number, UUID, or label
vb agent version diff 1 rc-2
vb agent version show rc-2 --json

# Restore a snapshot as a new immutable version (does not deploy)
vb agent version restore 1 --label rollback-v1

# Relabel a version without changing its immutable configuration
vb agent version label rc-2 approved \
  --description "Approved by the production readiness review"

# Test in staging while production continues running its existing version
vb agent version deploy approved --environment staging --display-name Staging

# After QA, promote by immutable number or UUID returned from save/list
vb agent version deploy 2 --environment production --display-name Production

# Roll back production without deleting history or changing staging
vb agent version deploy 1 --environment production

# Stop staging without deleting versions or changing production
vb agent environment undeploy staging

# CI/CD usage is non-interactive and must explicitly acknowledge the action
vb agent version deploy VERSION_UUID --environment production --yes --json
```

Version numbers above are examples: use the version actually returned from
save/list. Labels are mutable; use immutable numbers/UUIDs for release approvals.
All version commands and environment commands support `--json`. `versions` and
`environments` are aliases for the singular command groups.

| Command | Arguments and behavior |
| --- | --- |
| `vb agent version list` | `--json` returns `versions`, `environments`, and the latest 50 `deployments` audit entries. |
| `vb agent version show REF` | `--json` returns a `version` wrapper with redacted `config`. |
| `vb agent version restore REF` | Save the selected snapshot as a new immutable version without deploying. Supports `--label`, `--description`, `--accept-outbound-tos`, `-y`/`--yes`, and `--json`. |
| `vb agent version diff FROM TO` | Compare two immutable saved versions, not an environment pointer. |
| `vb agent version save` | `-f`/`--config-file`, `--label`, `--description`, `--accept-outbound-tos`, `-y`/`--yes`, `--json`. Omit the file to snapshot the saved editable config, not unsaved browser changes. |
| `vb agent version label REF [LABEL]` | Omit `LABEL` to clear it; `--description` updates the note. This edits metadata only. |
| `vb agent version deploy REF` | `-e`/`--environment` (default `production`), `--display-name`, `-y`/`--yes`, `--json`. |
| `vb agent environment list` | Show each environment's deployed version, status, timestamp, and available artifacts. |
| `vb agent environment undeploy ENVIRONMENT` | Preview and deactivate one environment. The environment slug is required: undeploy is irreversible, so it never defaults to production. Use `-y`/`--yes` for non-interactive runs. Only the agent owner can undeploy an environment whose preview reports `phone_will_be_released` or `telephony_reservation_will_be_stranded`; API keys are issued only for agents you own, so the CLI already runs as the owner. An Admin collaborator undeploying that environment from the dashboard gets **403**. |

Interactive save/deploy/undeploy displays a secret-safe review and requires
confirmation. Non-interactive runs require `--yes`. `--json` suppresses the printed
preview and outputs the final response; it does **not** bypass confirmation.
There is no CLI `--dry-run`: cancel the interactive preview or use the preview
API to capture a non-mutating review artifact.

When first enabling outbound calling in a phone-enabled candidate, accept the
Outbound Calling Terms of Use explicitly without deploying to production:

```bash
vb agent version save --config-file outbound-candidate.json --accept-outbound-tos
```

This sends `outbound_tos_accepted: true` only on save. `--yes` does not accept
outbound terms. Deploy the saved version separately after testing.

Saving a version that newly enables outbound calling requires the **current owner's plan or a partner outbound grant**, even for a web-only candidate. Telephony access and accepted terms do not grant outbound access. The CLI exits nonzero and the dashboard/public version API return a client error when that allowance is missing. Denied saves do not record consent, change the draft, create a version, or deploy. Existing outbound-enabled configurations can still be saved or edited after a downgrade; disabling outbound does not require outbound entitlement. New calls remain subject to runtime entitlements and usage limits. Restoring an older snapshot cannot bypass the check when it newly enables outbound.

Raw JSON config files are partial updates: omitted fields stay unchanged,
`model_settings` groups merge, and other supplied top-level fields/arrays replace
their existing value. Use `custom_prompt` and `mode`, not legacy `prompt`/`style`
aliases. A file containing the complete `version show --json` wrapper is treated
as a snapshot: model settings replace rather than merge, and the original version
ID supplies historical credentials for `__VB_SECRET_KEPT__` placeholders. Keep
that wrapper and those placeholders intact. Protect exported prompts/configs even
though secret fields are redacted.

Custom API-tool URLs (`api_tools[].url`) are fully redacted in CLI/API-key exports,
all dashboard historical-version reads, and every version/deployment diff,
including older stored audits. URLs can contain userinfo, arbitrary query
credentials, or opaque path tokens; even ordinary endpoint URLs are masked.
Preserve each tool's stable `id` (or `name` for older snapshots): reordered tools
restore their own URL from `source_version_id`, not another tool's or the current
draft's rotated credentials. An explicit replacement URL is honored. Live agent
execution, stored snapshots, and access to the current editable configuration are
unchanged. Previously downloaded artifacts are not retroactively redacted;
rotate any credentials exposed in them.

For direct version API calls, `full_snapshot` and `outbound_tos_accepted` must be
JSON booleans, not strings, numbers, or null; omission defaults to false. The CLI
already sends booleans. `"full_snapshot": false` preserves partial model-setting
merges; `"full_snapshot": "false"` is rejected instead of resetting omitted
settings. Only explicit `true` records new outbound consent; previously accepted
consent remains valid. Invalid flag types are rejected before saving or recording
consent.

Legacy PATCH / `vb config set/edit` / `vb prompt set/edit` still save and deploy.
If another save commits after their source draft was read, they return **409
Conflict**, including phone-restoration updates. Refresh and review before
retrying; the newer draft and live production remain intact.

With `vb agent version save`, explicit consent and the version save **succeed together**. If acceptance
cannot be recorded, the version is not saved and your existing configuration stays unchanged.
The first acceptance timestamp is preserved; an unchanged save can record consent
without a duplicate version. Preview never records consent. Legacy save-and-deploy may retain accepted consent even if deployment fails.

Each agent has **50 environments total, including production**, independent of
owner-wide phone capacity. Web-only, failed, inactive, and pending environments count.
Reuse stable `qa`/`staging` slugs rather than creating a name per build. A new name
beyond the cap returns **403** before allocation. Existing environments can still
be redeployed, including grandfathered agents above the cap. Undeploy releases
runtime resources but keeps the environment record, deployment audit, and versions.

`--display-name` / API `display_name` must be a string or null with at most 100
printable characters. Version descriptions reject terminal controls such as
ANSI/OSC escapes, while printable Unicode, newline, and tab remain supported.
Both CLI distributions escape controls in historical notes; `--json` preserves
the original value through JSON escaping.

Version descriptions must be a string or null, at most 2,000 characters after
trimming. Empty/whitespace/null clears a description; omission on metadata PATCH
preserves it. Invalid types return a client error (**400** API-key, **422**
dashboard), not a server error.

Environment names do not change call direction or grant access to a feature.
Existing production connections, active calls, and historical call records remain valid.
Issued tokens are not cryptographically revoked, but a token that has not started
a session cannot enter an inactive environment; redeploy it before testing new
sessions. Updating or rolling back an existing phone-enabled environment reuses
its phone resources when available. A failed update does not silently detach the
existing number or allocate a replacement number solely for a configuration change.

Labels are case-insensitively unique per agent, 1–120 printable characters after
trimming, and cannot be numbers, UUID-shaped, `.`/`..`, or contain `/` or `\`.
Descriptions allow 2,000 characters.
Environment names normalize to lowercase with spaces changed to hyphens and must
match `[a-z0-9][a-z0-9_-]{0,62}`. Display names allow 100 characters. Environments
are created on first deploy, not preview, and are not separate permission boundaries.
Labels/notes do not enforce release approvals.

Phone-enabled environments can provision separate numbers and consume telephony
capacity. Plan entitlements, quotas, and outbound terms still apply; use a
web-only config for QA when no test phone is needed. Snapshots do not clone
ownership, billing, collaborator access, OAuth grants, or external service state.

#### Integration guides and debug access

`vb docs` / `GET /api/v1/docs` and dashboard integration copy/preview describe the version deployed to **production**, not the saved draft. After changing modes, tools, or client actions, deploy to production and refresh the guide. An account key without a selected agent still receives generic docs. Integration guides do not select a named environment; inspect that environment's deployed snapshot separately.

`vb debug` and `vb debug --poll` use production's deployed `debug_mode`. Saving a debug enablement or disablement alone does not change access. Existing owner/admin and API-key permissions still apply; debug streams and stored events remain agent-wide rather than environment-specific.

If production is inactive or unavailable, guide and debug requests fail without exposing the saved draft. Reading these guides does not change versions, deployments, phone resources, keys, or billing.

#### Billing, usage, and isolation

Versions and environments share one logical agent and owner account. Saved versions
do not consume agent slots or create billable calls. **Test calls are real
usage**, including web-only QA calls: voice minutes, outbound/evaluation limits,
partner credits, and usage alerts remain owner-wide, not per environment. Existing
billing rules continue to apply; versioning creates no separate environment
subscription or free testing allowance.

Phone-enabled environments share a pool across all of the owner's agents, capped
at `min(plan agent limit + partner agent slots, 50)`. Production and staging with
separate phones use two reservations even for the same version/agent. Redeploying
an environment reuses its slot. Web-only environments reserve no phone slot, but
calls and tool side effects still cost usage. Failed cleanup retains the slot until
resources are retired; legacy phone creation/retry uses the same pool. The billing
page's agent count counts logical agents, not phone reservations.

If a phone deployment times out and its outcome cannot be confirmed, phone capacity remains reserved and redeployment, transfer, or deletion may be blocked until reconciliation. Inspect version history and environment status, then contact Vocal Bridge support if reconciliation is required. Do not repeatedly create replacement agents. Your previously deployed version remains selected until a deployment succeeds.

Redacted MCP round trips require unique stable IDs/names; ambiguous credentials return 400 without saving. Explicit existing configurations remain supported. Metadata PATCH updates only supplied fields; omission preserves concurrent edits and null clears a field.

Ownership transfer moves every phone reservation with the agent. The recipient
must have telephony entitlement and enough unused phone capacity, including for
retained cleanup inventory. Transfer checks serialize with other reservations;
insufficient capacity or an in-progress deployment leaves ownership, agent keys,
and collaborators unchanged. Web-only transfers need no phone capacity.

Explicit version deployment of a phone/both snapshot with outbound enabled rechecks the current owner's outbound plan/grant and accepted terms. Both version-deploy APIs return **403** before provisioning when either is missing; historical versions cannot restore access or consent. Save owner consent first, or save and deploy a version with outbound disabled. Existing deployments, inbound/web availability, and legacy save/redeploy contracts are unchanged; runtime call gates still apply.

Current owner entitlements apply after a downgrade; an old version does not restore
paid features or reset usage. Existing deployments are not automatically deleted.
Usage gates do not terminate calls already in progress. Shared links and outbound
APIs continue targeting production.

Environments are **not security boundaries**: keys, collaborator access, native
OAuth connections/revocations, and owner billing are shared. For isolated QA use
separate agents/accounts and sandbox credentials. Rollback cannot undo external
side effects or restore revoked credentials. Calls already admitted can finish
on their older version; new sessions select the deployed version.

Sharing and collaborator settings belong to the logical agent, not a version.
Saving, deploying, rolling back, or undeploying does not copy, reset, or version those settings.
Public talk links remain production-only; if production is undeployed, new talk-link
sessions stop until production is deployed again. Configuration-share links show the current
editable configuration rather than a named environment snapshot, and remain valid
until disabled or regenerated.

Treat returned room names as opaque. Named environments are isolated from one
another even when a `session_id` is reused. Version changes do not disconnect
active calls. Issued tokens are not cryptographically revoked, but admission
rejects new sessions for inactive environments.

See `vb docs` or `GET /api/v1/docs` for the complete billing/capacity table,
security limitations, and recovery guidance.

#### Bounded history pages

`vb agent version list` returns the newest 50 versions. Use `--limit 1..100` to
change the page size and `--before-version NUMBER` to fetch older versions. Human
output prints the next command; JSON includes `pagination.next_before_version`
(null on the last page). The API accepts the same `limit` and `before_version`
query parameters. Cursors are exclusive version numbers, so concurrent saves do
not shift older pages. The dashboard provides Older versions / Newer versions.
Deployed version summaries remain in `environments` regardless of the current
history page; show/diff/deploy can still address any saved version.

Use `vb agent environment undeploy ENVIRONMENT` to stop one environment while keeping the agent and its versions. Only the agent owner can undeploy an environment that releases its phone number, because the release is irreversible and returns capacity from the owner's telephony quota; in the dashboard an Admin collaborator receives **403** and the control is disabled with that reason. If cleanup remains pending on an inactive or failed environment, run the same command again to preview and retry release. Retrying an inactive environment does not create another undeploy audit. For `phone` and `both` targets, redeploy may provision a different phone number because a retired number is not guaranteed to be available again. Use the normal agent-deletion workflow only when the whole agent should be removed across all environments.

If a deployment is in progress, wait for completion and retry deletion. If ownership changes while deletion is pending, refresh and retry under the current owner.

#### Concurrency, CI/CD, and API parity

The CLI previews before each save/deploy and sends the preview's version ID as
`expected_latest_version_id` or `expected_deployed_version_id`. On `409`, read
state, wait for any in-progress deployment, then rerun to review a fresh diff.
Do not silently retry stale writes. For timeouts/5xx, inspect version history and
environment status first; a failed request is not proof nothing changed.

Direct API clients use `/api/v1/agent/versions` with `X-API-Key` and, for account
keys, `X-Agent-Id`. Save-preview is `POST /preview`; save is `POST` on the collection.
Deploy-preview is `POST /REF/deploy-preview`; deploy is `POST /REF/deploy`.
Carry the reviewed expectation into the write. Send explicit null for a new
environment's `expected_deployed_version_id`; omission disables that comparison.

Undeploy-preview is `POST /api/v1/agent/environments/ENVIRONMENT/undeploy-preview`.
Confirm with `POST /api/v1/agent/environments/ENVIRONMENT/undeploy` and echo
`expected_deployed_version_id`, `expected_deployment_status`, and `expected_updated_at`
from the preview. Undeploy makes new sessions fail closed, retires that environment's
phone/routing resources, and leaves versions, other environments, collaborators, and
sharing settings unchanged. Only the agent owner may undeploy an environment whose preview reports `phone_will_be_released` or `telephony_reservation_will_be_stranded`; a non-owner Admin receives **403** before anything changes. The second flag marks an undeploy that cannot prove the reserved telephony slot is unused, so the slot stays held in the owner's quota and no cleanup retry can release it. Undeploying production stops new public talk-link sessions;
configuration-share links remain available. If `cleanup_pending` is true, call the
same preview and confirmation routes again, unless `needs_operator_reconciliation` is also true: that marks retained capacity no retry can
release, so contact support instead. The inactive or failed cleanup preview
returns a null `expected_deployed_version_id`; retrying an inactive environment does not create another undeploy audit.

Deploy previews also return top-level `expected_display_name`, the stored friendly name before any proposed rename. Echo it (including null) to deploy to reject concurrent same-version renames with 409. Both CLI distributions and the dashboard do this automatically; older servers lacking the field remain supported.
Use `to_version.id` from a label-based deploy preview to pin the target.

Keep the **same environment and display name** between preview and deployment.
Changing either requires a **new diff review**: a deployed-version expectation
protects the selected environment's current state, but does not identify the
environment by itself. Two environments may run the same version or both be new.
The CLI retains its selected target while previewing and confirming.
In the dashboard, deployment previews are bound to the reviewed target; editing
the target or closing/reopening the dialog discards even in-flight previews.
Confirmation submits the reviewed agent, immutable version, environment, display
name, and expected current deployment, with target inputs locked until deployment finishes.

Changing a dashboard environment slug loads that target's existing friendly name,
including a custom production name. A new target starts with a blank optional name
so the server derives it from the slug. Select the slug before entering a rename.
CLI/API clients can omit `--display-name` / `display_name` to preserve an existing
name or derive a new one; an explicit name intentionally renames that environment.

The public deploy-preview API accepts `display_name` and returns the effective post-deploy
label in `environment.display_name`, without creating or renaming an environment.
Send the same target payload to preview and deploy. Omitted, null, or empty-string
display names preserve an existing name or derive a new one; invalid display names
are rejected during preview as well as deployment. Environment metadata is separate
from the immutable agent configuration, so a label-only rename can have zero
configuration changes in the diff.

**Connector ownership transfer:** connected accounts move with the agent, and the
recipient gains control of those connections. Authorization attempts that were not
completed before transfer must be restarted by the recipient. Disconnect before
transfer if a connected account must not move.
Existing connection grants, scopes, provider account identity, snapshots, and
deployments are preserved. Operations already accepted by an external provider may
finish; transfer does not cancel remote
requests or transfer ownership of the external account. Revocation affects every
environment sharing that connection.

Existing deployed-agent calls and token refresh remain available after transfer. Preserved grants require no provider reconsent.

`VOCAL_BRIDGE_API_URL` chooses the platform stack, while `--environment` chooses
an agent environment within that stack. Backend web-token callers may send
`{"environment":"staging"}` with `X-Agent-Environment: staging` to
`POST /api/v1/token`; its response includes
`environment`, `version_id`, and `version_number`. SDKs continue using the normal
token response. Authorize environment choices server-side; do not expose API keys
to clients. Missing/inactive named environments fail closed, while omitted
`environment` continues to use production. Do not assume outbound-call APIs accept
this web-token environment selector.

### Call Logs

```bash
# List recent call logs (default: 20)
vb logs
vb logs list

# List more logs
vb logs list -n 50

# Filter by status
vb logs list --status completed
vb logs list --status failed

# Paginate
vb logs list --offset 20 -n 20

# View details of a specific call
vb logs show <session_id>
vb logs <session_id>  # legacy shorthand

# Output as JSON
vb logs list --json
vb logs show <session_id> --json
```

For agents with post-call processing configured, `vb logs show` includes a `Post-processing` line indicating whether the post-call analysis/action run succeeded, timed out (10-minute limit), or failed — with a short reason. Same fields are available in `--json` output as `post_processing_status` and `post_processing_message`.

### Download Recordings

Download call recordings to your local machine.

```bash
# Download recording to current directory
vb logs download <session_id>

# Download with custom filename
vb logs download <session_id> -o call.ogg
```

Note: Recordings are only available if the agent has call recording enabled.

### Statistics

```bash
# Show call statistics
vb stats

# Output as JSON
vb stats --json
```

### Prompt Management

```bash
# Show current prompt and greeting
vb prompt show

# Edit prompt in your default editor ($EDITOR)
vb prompt edit

# Edit greeting instead
vb prompt edit --greeting

# Set prompt from file
vb prompt set --file prompt.txt

# Set prompt from stdin
echo "You are a helpful assistant." | vb prompt set

# Set greeting from file
vb prompt set --file greeting.txt --greeting
```

### Agent Configuration

Manage all agent settings including style, capabilities, and integrations.

```bash
# Show all agent settings
vb config show

# Show settings as JSON
vb config show --json

# Edit full config in your default editor ($EDITOR)
vb config edit
```

#### Export Config Sections

Export a specific config section as JSON. Output is pipe-friendly for roundtripping:

```bash
# Export current settings as JSON
vb config get model-settings
vb config get client-actions
vb config get mcp-servers
vb config get api-tools
vb config get ai-agent
vb config get builtin-tools
vb config get connectors

# Save to file, edit, then re-apply
vb config get model-settings > settings.json
# edit settings.json...
vb config set --model-settings-file settings.json
```

#### Discover Valid Options

Before updating settings, use `vb config options` to discover valid values:

```bash
# Show all available options for current agent style
vb config options

# Show options for a specific setting (by name or label)
vb config options voice
vb config options "TTS Model"
vb config options language

# Show all settings in a category
vb config options stt
vb config options audio
vb config options realtime

# Output as JSON
vb config options --json
```

#### Update Individual Settings

```bash
# Change agent style (Chatty, Focused, Gemini, Ultravox, Listener)
vb config set --style Focused

# Enable/disable capabilities
vb config set --debug-mode true
vb config set --hold-enabled true
vb config set --transfer-enabled true --transfer-destination +14155550123
vb config set --hangup-enabled true
vb config set --background-enabled false

# Update name or greeting
vb config set --name "My Agent"
vb config set --greeting "Hello! How can I help you today?"

# Set session limits
vb config set --max-call-duration 15
vb config set --max-history-messages 50

# End calls when the caller stays silent. After 120 seconds the agent checks in,
# waits through a 15-second warning window, then ends the call if there is still
# no caller activity. Any caller speech or configured client action resets it.
vb config set --end-call-on-user-silence true --user-silence-timeout 120
vb config set --end-call-on-user-silence false  # Disable

# Continuous speech ("keep talking" mode) — agent continues on its own after a
# short silence instead of waiting for the user each turn (tutors, narrators,
# guided experiences). The user can still interrupt at any time by speaking.
vb config set --continuous-mode true
vb config set --continuous-mode true --continuous-mode-delay 3   # wait 3s before continuing
vb config set --continuous-mode false  # back to normal turn-based behavior

# Set MCP servers from file
vb config set --mcp-servers-file servers.json

# Set model settings from file
vb config set --model-settings-file model.json

# Choose the background AI model (used for complex queries / MCP + API tools)
vb config set --background-model claude-sonnet-4-6   # auto | claude-haiku-4-5 | claude-sonnet-4-6

# Choose the post-call processing model
vb config set --post-processing-model gemini-2.5-flash   # auto | gemini-3.5-flash | gemini-2.5-flash | gemini-2.5-flash-lite

# AI Agent integration
vb config set --ai-agent-enabled true --ai-agent-description "Customer support agent"
vb config set --ai-agent-url "https://agent.example.com/vocal-bridge/query"
vb config set --ai-agent-protocol a2a --ai-agent-a2a-method message/stream
vb config set --ai-agent-response-mode multiple --ai-agent-response-ordering sequence
vb config set --ai-agent-late-responses speak --ai-agent-duplicate-responses ignore
vb config set --ai-agent-max-responses-per-turn 10 --ai-agent-max-chars-per-turn 12000
vb config set --ai-agent-header Authorization="Bearer <token>"
vb config set --ai-agent-param tenant_id=acme-prod
vb config set --ai-agent-file ai_agent.json
vb config set --ai-agent-enabled false  # Disable
```

Caller-silence termination is off by default. Its timeout accepts 30–600 seconds and cannot be enabled together with continuous mode, because continuous-mode agents intentionally keep the conversation moving during caller silence.

Suggestion: when updating a greeting, consider identifying the agent and company and including any disclosure, consent, or recording language your laws, regulations, or policies require.

#### Partial Updates with --merge

Use `--merge` to deep-merge file contents with current settings instead of replacing them. Only the fields you specify are changed:

```bash
# Update only the model, keeping all other settings intact
echo '{"realtime": {"model": "gpt-realtime-1.5"}}' > update.json
vb config set --model-settings-file update.json --merge

# Full roundtrip workflow
vb config get model-settings > settings.json
# edit settings.json to change only what you need...
vb config set --model-settings-file settings.json
```

`--merge` works with dict-based configs: `--model-settings-file`, `--builtin-tools-file`, `--ai-agent-file`, `--connectors-file`. Array-based configs (`--mcp-servers-file`, `--client-actions-file`, `--api-tools-file`) are always replaced.

#### Available Styles

| Style | Description |
|-------|-------------|
| **Chatty** | Best for snappy, low-latency conversations. Ideal when most context fits in the system prompt. |
| **Focused** | Best for information-heavy conversations like interviews or surveys. More thorough responses. |
| **Gemini** | Powered by Google Gemini Live API. Great for natural, flowing conversations. |
| **Ultravox** | Powered by Ultravox Realtime API. Optimized for voice-first interactions. |
| **Listener** | Passive observer that never speaks. Joins the room, transcribes multi-speaker audio with diarization, and streams coaching suggestions to your app via the data channel. Use for live coaching during multi-party calls (investor relations, sales, interviews). Web-only — no phone number provisioned. See `vb docs` after creation for the action schema, and the [Listener Mode Settings](#listener-mode-settings) section below for tunable behavior. |

### Listener Mode Settings

Listener-mode agents (`--style Listener`) accept additional settings that control coaching behavior. All settings are optional with sensible defaults; specify any subset.

| Flag | Range / values | Default | What it does |
|------|----------------|---------|--------------|
| `--coachee-description TEXT` | up to 500 chars | empty | Names the person you're coaching. When set, the agent only generates a coaching card when *someone else* is speaking (so it doesn't try to coach this person on their own words), and tailors each card as guidance for them. Example: `"the CFO during earnings Q&A"`. |
| `--coaching-debounce SECS` | 0–60 | 12 | Minimum seconds between coaching cards. Higher = fewer, more spaced-out suggestions; lower = more frequent. Set to 0 for back-to-back cards. |
| `--coaching-context-turns N` | 0–50 | 10 | How many recent turns of conversation the agent considers per coaching card. Higher = better-grounded; lower = faster and cheaper. |
| `--coaching-job-timeout SECS` | 5–120 | 30 | Maximum seconds to wait for each coaching card before giving up. Lower for snappier feedback; higher if your prompt relies on external data lookups. |
| `--coaching-gate true\|false` | — | true | When `true`, coaching only appears when the conversation matches the trigger conditions in your prompt. When `false`, every spoken turn produces a coaching card. |
| `--speaker-map true\|false` | — | true | When `true`, the agent identifies who's speaking (names, roles) as the conversation unfolds and sends `speaker_map_update` events. When `false`, your app only sees raw labels like `S0`, `S1`. |
| `--speaker-map-interval SECS` | 5–300 | 20 | How often the agent re-checks for new speaker identities. Lower = identities resolve faster. |

Examples:

```bash
# Set the coaching recipient and slow the cadence to one card every 20s
vb config set --coachee-description "the candidate being interviewed" \
              --coaching-debounce 20

# Turn off gating — get a coaching card for every spoken turn
vb config set --coaching-gate false

# Skip speaker identity inference entirely (you'll see only raw S0/S1 labels)
vb config set --speaker-map false

# Inspect or export current values
vb config options                 # lists all settings for the current agent
vb config get model-settings      # JSON dump of current settings
```

Each flag is also available on `vb agent create` for one-shot setup at deploy time.

### Outbound Calling (Paid Plans)

Place outbound phone calls through your agent. Requires an eligible paid plan and outbound calling enabled on the agent.

#### Enable Outbound Calling

Enabling outbound calling requires accepting the Outbound Calling Terms of Use:

```bash
# Enable outbound with ToS acceptance
vb config set --outbound-enabled true --accept-outbound-tos

# Set an outbound greeting (spoken when callee answers)
vb config set --outbound-greeting "Hi, this is a call from Acme Corp."

# Wait for the recipient to speak first before the agent talks
vb config set --outbound-wait-for-user true
```

**Outbound Calling Terms of Use:**
- **Compliance**: You are solely responsible for complying with all applicable laws, including the Telephone Consumer Protection Act (TCPA), the Telemarketing Sales Rule (TSR), and all state and local telemarketing regulations.
- **Consent**: You certify that you have obtained prior express consent from all individuals your agent will call, as required by applicable law.
- **Prohibited Uses**: You will not use outbound calling for unsolicited telemarketing, spam, robocalling, fraud, harassment, calls to emergency services, or any illegal or illicit purpose.
- **Indemnification**: Vocal Bridge bears no liability for claims, fines, or damages arising from your use of outbound calling. You agree to indemnify and hold Vocal Bridge harmless from any such claims.
- **Termination**: Vocal Bridge may monitor outbound calling activity and suspend or terminate access at any time for violations, without notice.

#### Place a Call

```bash
# Place an outbound call
vb call +14155551234

# With callee name
vb call +14155551234 --name "John Smith"

# Output as JSON
vb call +14155551234 --json
```

Phone numbers must be in E.164 format (e.g., `+14155551234`). Rate limits: 50 calls/day per agent, 200 calls/day per user.

### Ownership transfer and outbound consent

Outbound consent does not transfer. An ownership change removes the logical agent's prior consent across all environments. The recipient must explicitly accept the Outbound Calling Terms of Use before starting new outbound calls. Restoring or deploying an older version cannot restore consent.

In the dashboard, accept the outbound terms and **Save version**. CLI users can run `vb agent version save --config-file outbound-candidate.json --accept-outbound-tos`; public API clients send `outbound_tos_accepted: true` to `POST /api/v1/agent/versions`. Saving acceptance does not deploy. If the deployed version already enables outbound calling, new calls can resume after acceptance, subject to the recipient's existing usage limits and entitlements. `--yes` alone is not consent.

Untransferred agents and same-owner updates retain their acceptance. Transfer does not change snapshots, deployment pointers, phone resources, or inbound/web availability, and does not terminate already-admitted calls. A failed transfer rolls back the consent reset along with ownership.

### Background & MCP Testing

Test your agent's background AI — including any MCP servers, HTTP API tools, and connectors it has configured — by sending a query directly, without placing a call.

```bash
# Run a background query and print the result
vb mcp test "What's on my calendar tomorrow?"

# Adjust the timeout (seconds, 5-120) and get JSON
vb mcp test "Look up order 12345" --timeout 60 --json
```

### AI Agent Integration Testing

Preview delegated AI Agent responses from the CLI. Simulation mode uses Haiku as the AI Agent stand-in and follows your simulation prompt; endpoint mode calls your saved hosted endpoint. To hear the full voice handoff, use the dashboard Test tab and enable the Haiku simulated AI Agent during a browser voice call.

```bash
vb ai-agent test "What is the status of order 12345?" \
  --simulation-prompt "Act like our Acme support agent with access to order history."

vb ai-agent test --mode endpoint "What is the status of order 12345?"
```

### Post-Call Processing

Agents can run automated processing after each call ends (summaries, CRM updates, etc.). Configure the post-call prompt, an optional MCP server, and the model:

```bash
# Set the post-call processing prompt
vb config set --post-processing-prompt "Summarize the call and extract action items"

# Point post-processing at an MCP server (for post-call tool actions)
vb config set --post-processing-mcp-url "https://actions.zapier.com/mcp/..."

# Choose the post-call model
vb config set --post-processing-model gemini-2.5-flash
```

Test post-call processing against a sample transcript without placing a real call:

```bash
# Provide the transcript inline, from a file, or on stdin
vb post-processing test "Agent: Hello. User: I'd like to reschedule to Tuesday."
vb post-processing test --file transcript.txt
cat transcript.txt | vb post-processing test
```

> **Warning:** `post-processing test` runs your agent's live post-call tools — MCP, HTTP API tool, and connector actions can make real changes (e.g. creating records). Use a disposable/test transcript accordingly.

### Connectors

Native connectors let your agent use third-party services (e.g. Google Calendar) via OAuth. List available connectors and their status, and get a link to connect one:

```bash
# List connectors with connected / enabled-on-agent status
vb connectors list
vb connectors list --json

# Get a link to connect a connector (OAuth runs in your browser and auto-enables it on the agent)
vb connectors connect google_calendar
```

Connecting a connector in the browser auto-enables it on the selected agent. You can also export and adjust per-agent connector settings as JSON:

```bash
vb config get connectors > connectors.json
# edit connectors.json...
vb config set --connectors-file connectors.json --merge
```

### Debug Streaming

Stream real-time debug events from your agent during calls. First enable debug mode in your agent settings.

```bash
# Stream debug events via WebSocket (real-time)
vb debug

# Use HTTP polling instead (fallback)
vb debug --poll

# Adjust polling interval (only with --poll)
vb debug --poll -i 1.0
```

Debug events include:
- User transcriptions (what the caller says)
- Agent responses (what your agent says)
- Tool calls and results
- Background query results
- Session start/end events
- Errors

### Evals (Paid Plans)

Evals supports **Simulation** (a Gemini Live caller exercises the deployed agent end-to-end) and **Post** (score an existing recorded call). Gemini Developer API is the default; operators can explicitly switch the caller and scorer to Vertex AI. Both types support native, deterministic assertions for tool calls, bidirectional Client Actions, and AI Agent endpoint requests/responses. The original `vb eval` command remains the synchronous shortcut for Post evals and is fully backward compatible.

```bash
# Basic eval against the agent's own configuration
vb eval <session_id>

# With an explicit objective (what the agent should accomplish)
vb eval <session_id> --objective "Schedule an interview for next Tuesday"

# With both an objective and an expected scenario
vb eval <session_id> \
  --objective "Confirm the candidate's availability" \
  --scenario "User is busy and tries to reschedule twice"

# Long objective/scenario from files
vb eval <session_id> --objective-file objective.txt --scenario-file scenario.txt

# Raw JSON output (pipe-friendly)
vb eval <session_id> --json

# Create reusable Simulation and Post definitions
vb evals create --name "Appointment happy path" --type simulation --config simulation.json --assertions assertions.json --scoring-model gemini-3.1-pro-preview --environment staging
vb evals create --name "Call QA" --type post --objective "Resolve the request accurately"

# Queue runs, follow progress, and read retained results
vb evals list
vb evals run <eval_id> --scoring-model gemini-3.7-flash --wait --require-pass
vb evals run <eval_id> --environment staging --wait
vb evals run <post_eval_id> --session-id <session_id> --wait
vb evals runs
vb evals results <run_id> --wait --require-pass
vb evals cancel <run_id>
```

`vb evals create` fields:

| Flag | Purpose |
| --- | --- |
| `--name TEST_NAME` | Required durable test-case name shown in dashboards, run history, and automation. Prefer a workflow plus condition. |
| `--type simulation\|post` | Required execution type. Simulation places a synthetic voice call; Post scores a completed session supplied at run time. |
| `--config FILE` | Typed JSON configuration. Required for Simulation and must include `persona.primary_goal`; optional for Post. |
| `--assertions FILE` | JSON array of deterministic tool, Client Action, or AI Agent endpoint contracts. It replaces `config.assertions` when both are supplied. |
| `--scoring-model MODEL` | Qualitative evaluator: recommended GA/default `gemini-3.7-flash`, deepest-reasoning Preview `gemini-3.1-pro-preview`, or stable legacy `gemini-3.5-flash` / `gemini-2.5-flash`. Preview requires access and quota. Definitions set a default; eval runs and suite runs can override it. |
| `--objective TEXT` | Post only: outcome and quality bar the completed call should have achieved. Blank uses general call quality. |
| `--scenario TEXT` | Post only: caller, workflow, and constraint context the evaluator should assume. |
| `--environment NAME` | Simulation only: agent environment whose deployed version the synthetic caller dials. Defaults to `production`; `vb evals run --environment NAME` overrides it for one run batch. |
| `--json` | Print the created definition as JSON for scripts and CI. |

A Simulation dials the version **deployed** to its environment, never the draft in the editor, so saving a change does not alter what an eval scores until it is deployed. An environment with no active deployment is refused when the run is queued, before any eval credit or voice minute is spent.

In Simulation config, `persona` controls caller behavior (including `background_noise` and `disfluency`), `scenario` guides qualitative scoring, `stimuli` creates explicit app-to-agent test conditions, and `assertions` defines deterministic contracts. Preview those caller conditions with `vb evals voice-preview --background-noise light --disfluency moderate`. Eval Suite case `config` may select different caller conditions and `scoring_model` values; `vb evals suites run --scoring-model ...` temporarily overrides every child in one suite execution. Run `vb evals create --help` for inline guidance or see the complete field-by-field reference in [`docs/EVALS.md`](../../docs/EVALS.md#configuration-field-reference).

The session must already have a recording (check with `vb logs <session_id>`).

Simulation configuration, every API endpoint, and the durable run lifecycle are documented in [`docs/EVALS.md`](../../docs/EVALS.md).
Simulation output includes a weighted 0–100 qualitative breakdown plus a deterministic assertion gate with correlated, redacted input/output evidence. A critical assertion failure returns a nonzero CLI exit code; `--require-pass` also rejects partial qualitative verdicts. Legacy Post output keeps its existing 1–10 schema.

**Sample output:**

```
Call Evaluation
----------------------------------------
  Session:      550e8400...
  Score:        7/10
  Verdict:      partial

Summary:
  The agent answered the user's questions accurately but missed
  the scheduling objective when the user asked to reschedule.

What worked:
  + Greeted the caller naturally per the configured greeting
  + Recovered cleanly from a mid-sentence interruption

What didn't:
  - Did not call schedule_meeting tool when the user gave a date
  - Tone became impatient on the second reschedule attempt

Suggested prompt improvements:
  Add an explicit instruction to call schedule_meeting whenever
  the user proposes any time, including reschedules.
```

**Restrictions:**

- **Paid plan required** — `403` otherwise
- **Current plan or partner-grant eval limit** applies across Simulation and Post runs — `429` when exceeded
- **18 MB inline audio cap** per recording — extremely long calls will be rejected
- API keys, MCP server URLs, and other secrets in your agent's configuration are **not** sent to the evaluator

The default evaluator is Gemini 3.1 Pro Preview. Definitions, suite cases, eval runs, and suite executions may select one of the curated models; the immutable run snapshot and result provenance record the effective model.

### Developer Docs

Get integration documentation for building apps with your voice agent:

```bash
# Print integration docs (markdown)
vb docs

# Output as JSON
vb docs --json
```

Returns comprehensive documentation including:
- Agent configuration and capabilities
- MCP server, client actions, API tools, AI Agent integration
- API integration guide with token generation
- Implementation examples (JavaScript, React, Flutter)
- CLI and Claude Code plugin reference

Works with or without an agent selected. With an agent, docs include agent-specific configuration and tools.

## Configuration Files

### CLI Configuration

CLI settings are stored in `~/.vocal-bridge/config.json`:

```json
{
  "api_key": "vb_...",
  "api_url": "https://vocalbridgeai.com"
}
```

The config file has restricted permissions (600) to protect your API key.

### MCP Servers File

When using `--mcp-servers-file`, provide a JSON array:

```json
[
  {
    "url": "https://actions.zapier.com/mcp/...",
    "name": "Zapier",
    "tools": []
  }
]
```

### Model Settings File

When using `--model-settings-file`, provide a JSON object organized by category.

For Focused style:

```json
{
  "stt": {
    "model": "assemblyai:universal-streaming",
    "language": "en",
    "eot_threshold": 0.5
  },
  "tts": {
    "model": "eleven_multilingual_v2",
    "voice_id": "cgSgspJ2msm6clMCkdW9"
  },
  "session": {
    "max_call_duration_minutes": 30,
    "max_history_messages": 100,
    "end_call_on_user_silence": "true",
    "user_silence_timeout_seconds": 120
  }
}
```

`end_call_on_user_silence` is off by default. When enabled, the timeout must be 30–600 seconds. At the timeout the agent checks in and gives the caller 15 more seconds to respond before ending the call. Caller speech and configured client actions reset the inactivity timer. Do not enable it together with `session.continuous_mode`.

**Language options:**
- Preset: `en`, `multi` (auto-detect), `es`, `fr`, `de`, `pt`, `it`, `nl`, `ja`, `ko`, `zh`, `hi`, `ru`, `ar`, `pl`, `tr`, `vi`, `th`, `id`, `sv`, `da`, `fi`, `no`, `uk`, `cs`, `el`, `he`, `ro`, `hu`, `ms`, `bg`, `sk`, `hr`, `ca`, `ta`
- Custom: Use `language_source: "custom"` with `custom_language: "<BCP-47 code>"` (e.g., `en-US`, `pt-BR`, `zh-TW`)

For custom language code:

```json
{
  "stt": {
    "model": "deepgram:nova-3",
    "language_source": "custom",
    "custom_language": "pt-BR",
    "eot_threshold": 0.5
  }
}
```

### AI Agent Config File

When using `--ai-agent-file`, provide a JSON object:

```json
{
  "enabled": true,
  "description": "Customer support agent for Acme Corp",
  "verbatim": false,
  "endpoint": {
    "url": "https://agent.example.com/vocal-bridge/query",
    "protocol": "a2a",
    "a2a": {
      "method": "message/stream"
    },
    "headers": {
      "Authorization": "Bearer <token>"
    },
    "params": {
      "tenant_id": "acme-prod"
    }
  },
  "response_delivery": {
    "mode": "multiple",
    "ordering": "arrival",
    "late_response_behavior": "store",
    "duplicate_response_behavior": "ignore",
    "max_responses_per_turn": 10,
    "max_chars_per_turn": 12000
  }
}
```

**Fields:**
- `enabled` (boolean): Whether AI Agent integration is active
- `description` (string): What the developer's agent does (max 2000 chars). Helps the voice agent know when to delegate questions.
- `verbatim` (boolean): If true, the voice agent preserves responses exactly when direct TTS is configured; if false (default), it adapts for natural voice delivery. Chatty with OpenAI Native Voice uses strict generated-reply instructions and is best effort. For guaranteed verbatim delivery, set `model_settings.realtime.use_external_tts` to `"true"` and configure an ElevenLabs voice in `model_settings.tts`.
- `endpoint.url` (string): Optional HTTPS endpoint URL. When set, Vocal Bridge sends server-side `query_agent` requests there instead of requiring client-side delegation.
- `endpoint.protocol` (string): `http` (default) for the Vocal Bridge JSON contract, or `a2a` for Agent2Agent JSON-RPC.
- `endpoint.a2a.method` (string): `message/send` (default) or `message/stream`. Streaming can deliver progress/status chunks before the final answer in verbatim mode.
- `endpoint.headers` (object): Optional static headers sent with every endpoint request. Use this for auth or tenant routing. Header values are treated as secrets and hidden in CLI output.
- `endpoint.params` (object): Optional query params appended to every endpoint request. Values are treated as secrets and hidden after save.
- `response_delivery.mode` (string): `single` or `multiple` responses per `turn_id`. Defaults to `single` for HTTP endpoints, data-channel integrations, protocol-only configs without an endpoint URL, and non-streaming A2A `message/send` endpoints. Defaults to `multiple` only for configured A2A `message/stream` endpoints with a URL. Choose `single` for ordinary one-answer request/response agents and most non-A2A integrations. Choose `multiple` for A2A streaming, progress-plus-final flows, or any agent that intentionally sends more than one response for the same `turn_id`.
- `response_delivery.ordering` (string): `arrival` (default) speaks accepted responses as they arrive; `sequence` requires `agent_response.payload.sequence` starting at 1 and rejects out-of-order responses.
- `response_delivery.late_response_behavior` (string): `store` (default), `speak`, or `reject` for responses that arrive after the timeout grace period.
- `response_delivery.duplicate_response_behavior` (string): `ignore` (default) or `speak` for repeated response text.
- `response_delivery.max_responses_per_turn` (integer): hard cap for accepted responses on one `turn_id` (default 10, max 100).
- `response_delivery.max_chars_per_turn` (integer): hard cap for total spoken characters accepted on one `turn_id` (default 12000, max 50000).
- `endpoint_url` (string): Legacy alias for `endpoint.url`; still accepted for backwards compatibility.

Inline `--ai-agent-header` and `--ai-agent-param` flags merge into the existing map. To remove entries, provide a full replacement with `--ai-agent-file`.

## Examples

### Development Workflow

```bash
# 1. Check current agent setup
vb agent
vb prompt show

# 2. Make some test calls to your agent
# ...

# 3. Review the call logs
vb logs
vb logs show <session_id>  # detailed view with transcript

# 4. Download a recording for deeper analysis
vb logs download <session_id>

# 5. Update the prompt based on what you learned
vb prompt edit

# 6. Check statistics
vb stats
```

### CI/CD Integration

```bash
# Set API key via environment variable
export VOCAL_BRIDGE_API_KEY=$VOCAL_BRIDGE_API_KEY

# Update prompt from a file in your repo
vb prompt set --file prompts/production.txt

# Verify the update
vb prompt show
```

### Analyzing Call Logs

```bash
# Get all failed calls
vb logs --status failed --json | jq '.sessions[]'

# Get transcript of a specific call
vb logs <session_id> --json | jq '.transcript_text'
```

## Troubleshooting

### "No API key found"

Run `vb auth login` or set the `VOCAL_BRIDGE_API_KEY` environment variable.

### "Invalid API key"

- Check that your API key starts with `vb_`
- Verify the key hasn't been revoked in the dashboard
- Generate a new key if needed

### "Agent not found"

The API key may have been created for an agent that was deleted. Create a new key from an active agent.

### Connection errors

Check your network connection and that the API URL is correct.
